繁体   English   中英

在Swift中使用闭包声明变量后何时使用等号

[英]When to use equal sign after declare a variable with closure in Swift

我刚刚看到了Apple的示例代码:

let timeRemainingFormatter: NSDateComponentsFormatter = {
    let formatter = NSDateComponentsFormatter()
    formatter.zeroFormattingBehavior = .Pad
    formatter.allowedUnits = [.Minute, .Second]

    return formatter
}()

var timeRemainingString: String {
    let components = NSDateComponents()
    components.second = Int(max(0.0, timeRemaining))

    return timeRemainingFormatter.stringFromDateComponents(components)!
}

问题是:常量和变量都用闭包声明,但是一个带有等号,另一个则没有。 为什么?

()说“立即执行并返回结果”。 现在来一个长篇大论的答案:

let timeRemainingFormatter: NSDateComponentsFormatter = {
    // ...
}() // <- The '()' means "execute now and give me the formatter"

在初始化时间, timeRemainingFormatter将被计算一次 ,并且该值将被存储。 括号表示应立即执行闭包并返回结果,在这种情况下,应将其存储为属性。

var timeRemainingString: String {
    // ...
}

timeRemainingString将在每次调用时进行计算。


功能与闭包

更一般而言,在Swift中,函数仅被称为闭包。 定义一个类似的函数:

func myFunc() -> Void {
    print("Function")
}

与定义闭包几乎相同:

let myClosure: () -> Void = {
    print("Closure")
}

在这两种情况下,您都有一个名称( myFunc / myClosure ),一个呼叫签名( () -> Void )和一个代码块( { print(...) } )。

就像调用函数一样:

myFunc()

您可以将存储的闭包称为:

myClosure()

并且都将打印。

函数几乎只是定义命名闭包的一种便利。


在上下文中使用函数和闭包

假设您有一个全局函数和一个全局存储的闭包,分别定义为:

func myIntFunc() -> Int { return 1 }
let myIntClosure: () -> Int = { return 2 }

相似之处应该很明显。

现在,您想在类中将它们用作属性。 你会的

class MyClass {
    let funcInt:    Int = myIntFunc()    // would resolve to 1
    let closureInt: Int = myIntClosure() // would resolve to 2
}

请注意,两者的结尾都有() 那就是“执行我的函数/闭包以立即获取Int 。”

现在,假设您不想定义全局闭包; 您宁愿将该代码放在您的课​​程中,以使事情井井有条。 所以你也是:

class MyClass {
    let funcInt:    Int = myIntFunc()    // would resolve to 1
    let closureInt: Int = { return 2 }() // would resolve to 2
}

就像函数一样,您仍然需要执行闭包才能将Int移出闭包。 因此,就像函数一样,将()放在其后。


计算属性

最后,我们将涉及“计算的属性”。

var timeRemainingString: String {
    // ...
}

您可以将其视为编写不带任何参数的函数的一种方式,从而获得快捷调用签名(可以将其视为属性)。 确实就像闭包是由属性存储的,但是因为它是一种特殊的表示法,所以Swift知道执行闭包并在每次调用该属性时返回其结果。 因此,这是“计算的属性”。

你打电话时:

let timeRemaining = instance.timeRemainingString

Swift确实将其翻译为:

let timeRemaining = instance.timeRemainingString()

只需添加()即可使存储的闭包执行。

实际上,事情要复杂得多,因为您可以定义setter闭包以及刚刚讨论的getter,甚至还可以定义观察者闭包。 Swift会根据您要执行的操作类型将其分派到正确的闭包。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM