在Swift中输入IIFE的推断

时间:2014-08-06 14:40:14

标签: swift iife

IIFE(立即调用函数表达式)是JavaScript中使用的模式。 斯威夫特也看起来像支持那样。像这样:

let one = { 1 }
/// one: () -> Int

显式类型声明和常量复原函数效果很好。

let one:Int = { $0 }(1)
/// one: Int

但是常量返回函数不能推断出自己的类型。

let one = { $0 }(1)
/// SourceKitService
///    Terminated
///
/// Editor functionality
/// temporarily limited.

我强迫你像shell一样运行它。

// inferred.swift

#!/usr/bin/xcrun swift

var i:Int = 0
let id = { $0 }(i)

println(id)
  

在[./inferred.swift:4:10 - line:4:15]表达式的表达式@TF8inferredU_FRSiSi的详细的纺织品silgen closureexpr SIL函数RangeText =“{$ 0}”   [1] 29364分段错误./inferred.swift

我有什么遗漏或者我有错误的吗?

1 个答案:

答案 0 :(得分:3)

我相信我已经看到某些东西指的是Swift对这个构造的实现,并称为封闭"但是我现在还没有找到它。

请注意您的第一个示例:

let one = { 1 }

...不是一个叫做的闭包。它定义了一个闭包,但没有调用它。因为它没有参数,所以在通过在大括号后放置一个空参数列表来定义它的同时调用它:

let one = { 1 }()

您也应该可以使用类型推断来执行此操作:

let one = { $0 }(1)  // one: (Int) = 1

let i = 1            // i: Int = 1
let one = { $0 }(i)  // one: (Int) = 1

这些适用于测试版5,但如果i声明为var而不是let,则不会。 (只要你看到编译器或SourceKit崩溃,它可能对file a bug有好处。)


调用闭包对于设置延迟初始化的存储属性非常有用 - 第一个针对属性的get运行闭包例如,您将在Xcode项目模板中注意到它们以设置Core Data堆栈:

lazy var managedObjectContext: NSManagedObjectContext? = {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
    let coordinator = self.persistentStoreCoordinator
    if coordinator == nil {
        return nil
    }
    var managedObjectContext = NSManagedObjectContext()
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()

在这种情况下,必须明确给出类型 - 因为闭包可以返回nil,它的返回类型必须是可选的,但类型检查器不能告诉哪种类型的可选。