变量在其自己的初始值中使用,而变量在初始化后的闭包中使用
Posted
技术标签:
【中文标题】变量在其自己的初始值中使用,而变量在初始化后的闭包中使用【英文标题】:Variable used within its own initial value while variable is used inside a closure past init 【发布时间】:2015-07-12 22:22:28 【问题描述】:typealias CBType = () -> Void
class A
let b = B()
func test()
let token = b.register CBType in
self.b.waitFor([token]) // ERROR: Variable used within its own initial value
b.dispatch()
class B
private var _callbacks = [String:CBType]()
func register(callback: CBType) -> String
let id = "1234"
_callbacks[id] = callback
return id
func dispatch()
for (_, cb) in self._callbacks
cb()
func waitFor(tokens: [String])
A().test()
当我修改测试函数以使用实例变量时,一切都恢复正常了,但语法感觉有点重。
class A
let b = B()
var token: String?
func test()
token = b.register CBType in
self.b.waitFor([self.token!])
b.dispatch()
为什么我不能在闭包中使用局部变量,因为当闭包最终被调用时它会经过初始化?
【问题讨论】:
【参考方案1】:常量token
在被闭包捕获时没有值。
您可以改用可变变量,闭包将捕获变量而不是其值。
func test()
var token = ""
token = b.register
self.b.waitFor([token])
b.dispatch()
或者,您可以将令牌作为参数传递到闭包中:
typealias CBType = (String) -> Void
class A
let b = B()
func test()
let token = b.register theToken in
self.b.waitFor([theToken])
b.dispatch()
class B
private var _callbacks = [String:CBType]()
func register(callback: CBType) -> String
let id = "1234"
_callbacks[id] = callback
return id
func dispatch()
for (id, cb) in self._callbacks
cb(id)
func waitFor(tokens: [String])
println("Wait for \(tokens)")
A().test()
【讨论】:
【参考方案2】:在您的第一个示例中,当您拨打电话 self.b.waitFor([token])
时,token
没有值。
在您的第二个示例中,一切似乎都可以正常工作,因为通过像这样声明 token
:var token: String?
它被赋予了一个初始值 (nil
)。
问题不在于您是否使用实例变量 -vs- 局部变量(或者它在闭包中使用),问题在于(在第一个示例中)您正在尝试使用 @987654326 @ 在提供其初始值的表达式中。
相当于这样声明Int
:let myValue: Int = myValue + 1
- 它的初始值应该是“what”+1?
【讨论】:
我意识到这一点,但我仍然对闭包只是一个函数指针这一事实感到困惑:在调用闭包之前不会运行函数代码。那么,如果在执行闭包代码之前没有引用相同的变量,为什么编译器会坚持初始化变量呢? 编译器正在完成它的工作:) 没有可能的条件可以成功初始化token
,因此错误 re: 在设置其初始值时引用自身 - 我很感激它足够聪明,给我这些错误!
@JohnDifool 你的预感是正确的。这里没有问题,这适用于 Haskell 等其他语言,被称为“打结”。这是一个快速的缺陷。以上是关于变量在其自己的初始值中使用,而变量在初始化后的闭包中使用的主要内容,如果未能解决你的问题,请参考以下文章