I noticed that type(of:) has this unexpected signature:
func type<T, Metatype>(of value: T) -> Metatype whereas I would have expected:
func type<T>(of value: T) -> T.Type The actual signature somehow takes 2 independent and unbounded type parameters, uses one of them as the parameter type, and the other as the return type. This seems to suggest that I can do something silly like this:
let foo: String = type(of: 1) // T is Int, Metatype is String But when I actually tried it,
Cannot convert value of type 'Int.Type' to specified type 'String'
So I don't get to specify Metatype after all, even though it's a generic type parameter. I was curious how the compiler did this, so I went to the source code and checked. I think what's preventing me from doing that silly thing is this @_semantics annotation:
@_transparent @_semantics("typechecker.type(of:)") public func type<T, Metatype>(of value: T) -> Metatype { I also saw some comments explaining that the implementation written here isn't actually called, and that this is directly handled by the type checker itself. But that doesn't answer my question - why does type(of:) return a completely unrelated type parameter Metatype, rather than T.Type?
My guess is that there is some edge case where type(of:) will return a completely unrelated type to T, but I have no idea what that is.
没有评论:
发表评论