首页 > 解决方案 > Swift closures, closure signatures, and closure equivalence

问题描述

I'm kind of curious why this closure assignment works in Swift 4.1 (not tested yet under Swift 4.2, but both snippets don't work in Swift <= 4.0):

func intArrayFunc(_ policy: Int = 0,  completion: (([Int]?, Error?) -> Void)? = nil) {
    print("policy = '\(policy)'")
    completion?([policy + 2], nil)
}

typealias anyArrayClosure = (Int, (([Any]?, Error?) -> Void)?) -> Void

let a: anyArrayClosure = intArrayFunc(_:completion:)

a(1) { (results, error) in
    results?.forEach({ (result) in
        if let oneResult = result as? Int {
            print("\(oneResult) (Should be 3)")
        }
    })
}

However, this doesn't:

func t1(_ int: Int = 0, array: [Any]? = nil) {
    print("t1")
}

func t3(_ int: Int = 0, array: [Int]? = nil) {
    print("t3")
}

typealias function = (Int, [Any]?) -> Void

let t2: function = t1
let t4: function = t3

Or is it a just a bug in the 4.1 compiler?

标签: swiftxcode

解决方案


观察 1

func t1(_ int: Int = 0, array: [Any]? = nil, completion: ((Int) -> ())) {
    print("t1")
}

func t3(_ int: Int = 0, array: [Any]? = nil, completion: ((Int) -> ())) {
    print("t3")
}

typealias function = (Int, [Int]?, ((Any) -> ())) -> Void

let t2: function = t1
let t4: function = t3

是有效的,因为t2andt4将采用与in和Int兼容的参数,但如果你做相反的事情,它不会因为,不能接受一个值。Anyt1t3IntAny


观察 2

现在闭包再次收到一个参数。因此,如果将Int参数传递给Any它是有效的,但如果你传递Any给 an Int,则不是。

所以,这行不通

func t1(_ int: Int = 0, array: [Any]? = nil, completion: ((Int) -> ())) {
    print("t1")
}

func t3(_ int: Int = 0, array: [Any]? = nil, completion: ((Any) -> ())) {
    print("t3")
}

typealias function = (Int, [Int]?, ((Int) -> ())) -> Void

let t2: function = t1
let t4: function = t3

因此,最终归结为一个简单的事实,即您传递给变量的任何内容都应该与其类型兼容。您可以传递和传递,IntAny反之亦然。


推荐阅读