ios - 为什么 Swift 推断元类型“Any.Type”而不是类型“Any”?
问题描述
func giveMeZero<T>() -> T? {
print(T.self)
return 0 as? T
}
当在没有足够类型上下文的情况下调用上述函数时,Swift 将返回类型推断为元类型“Any.Type”,我希望它推断出“Any”或者可能会提供歧义错误。
// Calling code without type context, which exhibits the said behaviour
// prints 'no', since it's trying to cast 0 to Any.Type
if giveMeZero() != nil {
print("yes")
} else {
print("no")
}
输出:
"Any.Type\n"
"no\n"
解决方案
为什么T
不是Any
这很简单。没有为and==
定义运算符,因为is not 。不可能。Any?
Any?
Any
Equatable
T
Any
为什么T
可以Any.Type
这也很简单。有这样一个内置的运算符与此签名完全匹配。
func == (t0: Any.Type?, t1: Any.Type?) -> Bool
为什么不模棱两可
这更微妙。你会认为这T
可能是String
orInt
或Float
,对吧?毕竟,它们都是Equatable
,并且对于所有Equatable
类型,都为它们Optional
定义了==
和!=
。但是,似乎在全局范围内声明的运算符被认为比在 的条件扩展中声明的运算符“更好” Optional
,因此运算符重载决策总是首先选择非扩展运算符。这是合理的——毕竟,添加扩展不应该导致旧代码中断。
例如,添加此代码会使您的代码产生“模棱两可”的错误:
struct Foo {}
func ==(lhs: Foo?, rhs: Foo?) -> Bool {
true
}
func !=(lhs: Foo?, rhs: Foo?) -> Bool {
false
}
新添加的!=
运算符 forFoo?
和内置的运算符 forAny.Type?
被认为同样适合调用giveMeZero() != nil
。
但是,这不会:
struct Foo { }
extension Optional where Wrapped == Foo {
static func ==(lhs: Foo?, rhs: Foo?) -> Bool {
true
}
static func !=(lhs: Foo?, rhs: Foo?) -> Bool {
false
}
}
推荐阅读
- python-3.x - 是否可以为 bdist_wheel 设置 top_level?
- c# - 如何让玩家在坠落时死亡?
- flutter - 颤振流行到新路线
- php - Drupal 在动态创建的元标记中转义 url
- dialogflow-es - 轮播中的项目不能在智能显示器上点击/选择
- python - 从 n 人的团队中形成 r 组的最佳方法,但尽量减少重叠
- python - 使用 matplotlib 针对正态分布、高斯分布、指数分布和伽马分布创建动画的问题
- ios - 如何在标签中添加按钮?
- http - 如何为 AAD 生成 Http 请求?
- haskell - 将 Int 定义为 Haskell 中类型类的实例时出现问题