REPL 允许在 var 或 let 之后重新声明 var 或 let,如果在单独的行中输入。
这个例子在 REPL 中是允许的,但在 swiftc 中是不允许的:
$ swift
Welcome to Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.4).
Type :help for assistance.
1> var x = 10
x: Int = 10
2> let x = 20
x: Int = 20
3> let x = 30 // allowed in REPL
x: Int = 30
如果短语逐行输入,您可以在 REPL 中 re-let 和 re-var。
但是 REPL 不允许在一行中重新声明(使用分号),或者如之前的回答中提到的,在粘贴的块中:
4> let y = 30; let y=20
error: repl.swift:18:17: error: invalid redeclaration of 'y'
还要注意,调用 /usr/bin/swift 的 shebang/hashbang 脚本将使用 swiftc 而不是 REPL。可能令人困惑的是,swiftc 和 swift 以及 REPL 都是同一个/usr/bin/swift
#!/usr/bin/swift
let x = 10
let x = 20 // not allowed
函数的重新声明以同样的方式被允许:
> func x() {}
> func x() {} // allowed in REPL
> func y() {}; func y() {}
error: repl.swift:7:19: error: invalid redeclaration of 'y()'
正如我们所料,函数重新声明适用于完整的函数签名。声明重载将声明一个新函数,该函数将与同名但具有不同参数的现有函数一起存在。这意味着重载不一定会重新声明以前的同名函数。
让我们声明一些重载函数,让我们在一行中完成所有这些来证明它们在 REPL 中是允许的。
> func y(_:Int) {print("y Int")}; func y(_:String) {print("y String")};
> y(3)
y Int
> y("Y")
y String
有两个函数,并且都具有相同的名称。一个采用 Int,另一个采用 String。让我们重新声明一个 Int:
func y(_:Int) {print("y Int new")};
> y(3)
y Int new
就是这样:输出显示它被重新声明了。
如果您不习惯捕获,事情可能会变得混乱(或危险)。观察当范围内的变量被捕获时会发生什么:
> var xx=10;
xx: Int = 10
> func x(){print(xx)}; x()
10
这很直观。但是当我们重新声明捕获的变量时会发生什么:
> var xx=10; x()
10
xx: Int = 10
一切都还好吗?不,等等……
> xx=20; x()
10
为什么是 10 而不是 20?在 x() 内部,它仍然是第一个 var xx=10 在范围内并被捕获。这就是捕获的工作方式。但请注意,捕获的变量在 REPL 提示符下不再存在。重新声明捕获的变量不会自动重新捕获它。
有时我使用 REPL 来挖掘错误或语言结构,最好了解这些细微之处,因为它们可能会导致您对代码中发生的事情感到困惑,或者可能导致对代码的误解语言。
REPL 函数重载和 var/let 重新声明都在前面回答中提到的博文中有解释,见https://developer.apple.com/swift/blog/?id=20
我想我会总结之前的答案和 cmets 中的一些发现,并添加更多细节。