let arrenum = Array(arr.enumerated())
So why is this illegal?
extension Array {
func f() {
let arrenum = Array(self.enumerated())
// error: type of expression is ambiguous without more context
}
}
Edit seems to be a solution:
extension Array {< br /> func f() {
typealias Tup = (offset:Index, element:Element)
let arrenum = Array(self.enumerated())
}
}
But why is it necessary? (Is it?)
For example:
struct S{
func foo(_ other: S) {// parameter inferred to be `S`.
let x = S() // `x` inferred to be `S`.
}
}
extension S {
func bar(_ other: S) {} // same in extensions too.
}
This is convenient, but the error you encounter is that Swift will always make this inference, even if it is incorrect .
So, in your example:
extension Array {
func f() {
let arrenum = Array(self.enumerated())
// error: type of expression is ambiguous without more context
}
}
Swift interprets the code as let arrenum = Array
One of the solutions you have found is to explicitly specify the placeholder type to prevent the compiler from making this wrong inference.
< p>
extension Array {
func f() {
l et arrenum = Array<(offset: Int, element: Element)>(self.enumerated())
}
}
Another possible solution seems to be to use completely Qualified type, for example:
extension Array {
func f() {
let arrenum = Swift.Array(self.enumerated())
}
}
Because it seems that Swift does not make the same inference for fully qualified types (I’m not sure if you should rely on this fact).
It’s worth it in the end Note that instead of calling the initializer of Array, use map(_:) instead to avoid this problem completely:
extension Array {
func f() {
let arrenum = self.enumerated().map {$0 }
}
}
Like the initialization call, it will return a set of offset element pairs.
This is legal (arr is an array):
let arrenum = Array(arr. enumerated())
So why is this illegal?
extension Array {
func f() {
let arrenum = Array(self.enumerated())
// error: type of expression is ambiguous without more context
}
}
Edit seems to be a solution:
extension Array {< br /> func f() {
typealias Tup = (offset:Index, element:Element)
let arrenum = Array(self.enumerated())
}
}
But why is it necessary? (Is it?)
This is a known bug (SR-1789). Swift currently has a feature that you can use in its own body Refer to generic types without repeating their placeholder types-the compiler will infer that they are the same as your own types.
For example:
< pre>struct S
func foo(_ other: S) {// parameter inferred to be `S
let x = S() // `x` inferred to be `S
}
}
extension S {
func bar(_ other: S) {} // same in extensions too .
}
This is very convenient, but the error you encounter is that Swift will always make this inference, even if it is incorrect.
So, in In your example:
extension Array {
func f() {
let arrenum = Array(self.enumerated())
// error: type of expression is ambiguous without more context
}
}
Swift interprets the code as let arrenum = Array< Element>(self.enumerated()), because You are in the body of Array
One solution you have found is to explicitly specify the placeholder type to prevent the compiler from making this incorrect reasoning.
extension Array {
func f() {
let arrenum = Array<(offset: Int, element: Element)>(self.enumer ated())
}
}
Another possible solution seems to be to use fully qualified types, for example:
extension Array {
func f() {
let arrenum = Swift.Array(self.enumerated())
}
}
Because it seems Swift does not make the same inference for fully qualified types (I am not sure if you should rely on this fact).
Finally, it is worth noting that instead of calling the initializer of Array, use map(_: ) Instead of avoiding this problem completely:
extension Array {
func f() {
let arrenum = self.enumerated().map {$0}
}
}
Like the initialization call, it will return a set of offset element pairs.