简体   繁体   中英

Type Inference of IIFE in Swift

IIFE(Immediately-Invoked Function Expression) is so many used pattern in JavaScript. Swift also looks like supproting that. Like this:

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

and explicit type-declared and constant-retured function works well.

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

but constant-returnd function cannot be inferred own type.

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

and I force to run this like shell.

// inferred.swift

#!/usr/bin/xcrun swift

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

println(id)

Whemphasized textile silgen closureexpr SIL function @_TF8inferredU_FRSiSi for expression at [./inferred.swift:4:10 - line:4:15] RangeText="{ $0 }" [1] 29364 segmentation fault ./inferred.swift

Is there something I missed or did I have wrong styntax?

I believe I've seen some something referring to Swift's implementation of this construct as "called closures", but I'm failing to find it now.

Note that your first example:

let one = { 1 }

... is not a called closure. It defines a closure, but does not invoke it. Because it has no parameters, you call it at the same time you define it by placing an empty parameter list after the braces:

let one = { 1 }()

You should be able to do this with type inference, too:

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

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

These work for me on beta 5, though not if i is declared with var instead of let . (Any time you see the compiler or SourceKit crash it's probably good to file a bug .)


Called closures can be great for setting up lazily-initialized stored properties -- the first get against the property runs the closure For example, you'll notice them in the Xcode project templates for setting up a Core Data stack:

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
}()

In this case the type has to be explicitly given -- because the closure can return nil , its return type has to be an optional, but the type checker can't tell what kind of optional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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