young
(rtSwift)
1
I thought tuples are equivalent if types are the same regardless of label names?
enum Choice: CaseIterable {
case a, b, c, d, e, f
}
let bitMap = Dictionary<Choice, Int>(uniqueKeysWithValues: Choice.allCases.enumerated().map {
(key: $1, value: 1 << $0) // error: Initializer 'init(uniqueKeysWithValues:)' requires the types '(key: Choice, value: Int)' and '(Choice, Int)' be equivalent
// ($1, 1 << $0) // this works
})
Xcode Version 13.0 beta 5 (13A5212g)
young
(rtSwift)
3
But it seems unlabeled tuple can become labeled with no type mismatch?
func foo() -> (a: Int, b: Int) {
// these all work:
(1, 2)
// (a: 1, 2)
// (1, b: 2)
}
print(foo()) // (a: 1, b: 2)
is no label is same as any label?
Because the compiler infers the labels due to the return type of the function.
Just like in the examples from the docs:
var someTuple = (top: 10, bottom: 12) // someTuple is of type (top: Int, bottom: Int)
someTuple = (top: 4, bottom: 42) // OK: names match
someTuple = (9, 99) // OK: names are inferred
1 Like
young
(rtSwift)
5
This is why I'm confused, no type mismatch compile error when the second element is not bit shift for the same mismatched labeled tuple:
enum Choice: CaseIterable {
case a, b, c, d, e, f
}
let bitMap = Dictionary<Choice, Int>(uniqueKeysWithValues: Choice.allCases.enumerated().map {
// (key: $1, value: 1 << $0) // error: Initializer 'init(uniqueKeysWithValues:)' requires the types '(key: Choice, value: Int)' and '(Choice, Int)' be equivalent
// (key: $1, value: $0) // 👈 !!! exact same tuple as above, now no problem!
(truck: $1, you: $0) // no matter what the labels are, all no problem!
// ($1, 1 << $0) // this works
})
Seems like the bit shift one produce compile error, others fine
func generic<T>(_ closure: () -> (T, T)) -> (wtf: T, hey: T) {
closure()
}
print(generic { (truck: 1, you: 2) }) // (wtf: 1, hey: 2)
From the above example, it seems labeled tuple can become unlabeled, and from unlabeled tuple to labeled:
labeled-tuple -> unlabeled-tuple -> labeled-tuple
this appears to be a valid way to re-label a tuple.
So I don't see why my original case should not compile. It's clearly not caring what the tuple element labels are if it ends in an unlabeled-tuple.
Interestingly, this gives no errors:
let bitMap = Dictionary<Choice, Int>(uniqueKeysWithValues: Choice.allCases.enumerated().map {
let i = 1 << $0
return (key: $1, value: i)
})
And this works too:
let bitMap = Dictionary<Choice, Int>(uniqueKeysWithValues: Choice.allCases.enumerated().map {
let t = (key: $1, value: 1 << $0)
return t
})
I don't really understand why.