Reputation: 1845
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?
Upvotes: 0
Views: 180
Reputation: 11243
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
This works because t2
and t4
will take Int
arguments which are compatible with the Any
in t1
and t3
, but if you do the opposite it won't because, Int
cannot accept an Any
value.
Now the closure is again receiving an argument. So if pass an Int
argument to Any
it is valid, but if you pass Any
to an Int
, it isn't.
So, this doesn't work.
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
So ultimately, it boils down to the simple fact that whatever you are passing to a variable should be compatible with it's type. You can pass and Int
to Any
but not vice-versa.
Upvotes: 1