代码之家  ›  专栏  ›  技术社区  ›  devtech

快速提升?[已关闭]

  •  0
  • devtech  · 技术社区  · 10 年前

    众所周知,JavaScript将变量“提升”到文件或范围的顶部。但根据我的理解 let 与相同 var 只有 允许 仅限于其定义的范围。

    作为一种编译语言而不是解释语言,我们能假设Swift不这样做吗?

    例如:

    x = 10
    
    var y = x + 10
    
    var x
    
    2 回复  |  直到 10 年前
        1
  •  7
  •   Community Mohan Dere    9 年前

    我们能假设斯威夫特没有这样做吗?

    你可以随心所欲,但无论编程语言如何,你绝对最好的选择是尝试一下,然后找出答案。如果您将示例代码粘贴到Playground或任何支持Swift的IDE中,或者尝试通过命令行运行它,您会很快发现这根本不起作用。


    你的问题有些令人困惑,但我想我可以回答你的所有或至少大部分问题。

    x = 10    
    var y = x + 10
    var x
    

    假设没有其他代码可以与原始示例一起使用,那么它就不会编译。这三条线都有问题。

    前两行抱怨使用了未识别的“x”。在英语中,这意味着斯威夫特不知道你在说什么变量。Swift中的变量必须在使用之前声明,因此第三行的声明对后面的两行没有帮助。

    第三行抱怨说它不知道什么类型 x 应该是。“模式中缺少类型批注”。在某些情况下,Swift可以确定变量的类型。例如,使用 var x = 10 ,斯威夫特可以理解 x(x) 的类型应为 Int 。如果我们想要其他东西,我们必须指定。但如果我们不在声明中赋值,Swift就不知道,必须告诉我们: var x: Int?


    如果是这样的情况 x(x) 存在于不同的范围?

    嗯,Swift允许可变阴影。也就是说,在一个范围内声明的变量隐藏了在另一个范围中声明的变量。

    因此,例如:

    class Foo {
        let x = 10
    
        func foo(value: Int) -> Int {
            let a = value * self.x
            let x = 10
            return a * x
        }
    }
    

    现在我们可以使用 一些 x(x) 在我们声明本地作用域之前 x(x) ,但这些是不同的变量。此外,也许最重要的是,请注意 self. 预先准备好 x(x) 在这里这是必需的。没有它,Swift将拒绝编译此代码,并将抱怨:“在声明之前使用局部变量‘x’。”


    然而,在类的函数中并不是唯一可以隐藏变量的地方。我们也可以在 if 块(以及其他地方),这是事情可能变得更混乱的地方。考虑一下:

    class Foo {
        let x = 10
    
        func foo(value: Int) -> Int {
            print(x)
            if x > 3 {
                let x = 2
                print(x)
            }
            return x
        }
    }
    

    在这里,我们使用了 x(x) 两次之后才宣布。我们不必利用 自己 而且它没有抱怨,编译得非常好。但需要注意的是 外部 这个 如果 块(包括 x > 3 有条件的) x(x) 我们引用的是实例变量,但在 如果 块,我们创建了一个名为 x(x) 这会遮蔽实例变量。我们也可以使用 if let 和 if var 构造(但不是 guard let ).

    调用此函数的结果是 10 打印后,我们输入 如果 块的值 2 打印,然后退出 如果 块的值 10 返回。


    现在让我们结束 var 在这里混合。首先,如果你还没有意识到,你应该从阅读开始 this 这解释了 let 和 变量 (一个是常数,另一个不是)。

    让我们结合起来 允许 与 变量 使用范围和变量阴影来查看它是如何影响事情的。

    class Foo {
        let x = 10
    
        func foo(value: Int) -> Int {
            print(x)
            if x > 3 {
                var x = 2
                while x < 10 {
                    print(x)
                    x += 3
                }
                return x
            }
            return x
        }
    }
    

    好的,这和以前一样,但在 如果 块

    这里,我们的局部范围变量被声明为 变量 而我们的实例变量保持不变 允许 。我们不能修改实例变量,但可以修改局部变量。我们在每次迭代 while 环

    但重要的是,这个变量与实例变量完全不同。它可能有一个完全不同的名称(实际上,它基本上总是 应该 具有不同的名称)。所以修改我们的局部变量 x(x) 不会改变范围更广的实例变量 x(x) 它们是驻留在不同内存位置的不同变量。一旦变量声明为 允许 或 变量 ,该变量不能更改为另一个。

        2
  •  2
  •   Eppilo    10 年前

    “let”和“var”在范围上没有区别。

    全局变量是在任何 函数、方法、闭包或类型上下文。局部变量为 函数、方法或闭包中定义的变量 上下文