I hit some confusing error messages from the Swift compiler ('A' is not convertible to 'A'
, 'E' is not identical to 'E'
) and I think it's because I introduced identically named type variables in two scopes, where one scope was nested inside the other.
I'd like to get a more complete idea of how type variables work, and so I have a few related questions:
- what is the scope of type variables in Swift?
- ow is the scope affected by nested types and methods?
- can type variables be shadowed?
- what happens when a nested method introduces a type variable of the same name as an enclosing class?
- is it possible to do something like
method2
(below)? (my XCode kept crashing and I wasn't able to figure this out)
Here are a few examples to show what I'm trying to figure out:
class MyClass<A> {
func method1<A>(a:A) -> A {
// what does A refer to here?
return a;
}
class func staticmethod<A>(a:A) -> A {
// what does A refer to here?
return a;
}
func method2() -> ((A) -> A) {
// is this even possible?
// I'm not sure how to write method2's type !
func id<A>(a:A) -> A {
return a;
}
return id;
}
}
The scope of the generic type of a generic class/struct/method/function is exactly the class/struct/method/function. And yes, it can be shadowed by nested definitions.
In your example,
A
inmethod1
is the generic type for that method and will be replaced by the actual type when the method is called. It shadows the generic type ofMyClass<A>
. Example:The same is true for the static method:
In your
method2
, the inner function does not get a type parameter, it should be (and I have removed one pair of unnecessary parentheses):or
depending on whether it works with the type of the class or introduces its own generic type. Note that you can shorten that using a closure instead of an nested function, e.g.
In the first case you would use it like
and in the second case you could do
Here the actual type of
method2b<A>
is inferred from the argument "bar" asString
.Generally, I would prefer to use different names for nested generic types to avoid unnecessary confusion.