【发布时间】:2017-05-19 14:50:41
【问题描述】:
我有一个协议和两个类,其中一个采用它
protocol A { }
class B1 { }
class B2: A { }
我想要一个泛型类的计算属性,这取决于该类型是否采用A。我试过这个
class C<T> {
var v: Int { get { return 0 } }
}
extension C where T: A {
var v: Int { get { return 1 } }
}
现在 C<B1>().v 返回 0,但 C<B2>().v 抱怨 v 的使用不明确。如果我把v 变成一个可行的方法
class D<T> {
func v() -> Int { return 0 }
}
extension D where T: A {
func v() -> Int { return 1 }
}
现在C<B1>().v() 返回 0,C<B2>().v() 返回 1,正如预期的那样。
为什么 getter 方法与方法方法不同?我可以使计算的属性工作吗?我试过了
class E<T> {
var v: Int { get { return get() } }
func get() -> Int { return 0 }
}
extension E where T: A {
func get() -> Int { return 1 }
}
但现在E<B1>().v 和E<B2>().v 都返回0,即只使用get 的无约束实现。我可以“强制”编译器选择正确的实现吗?
有什么想法吗?对我来说,这听起来像是 Swift 的一个不足/错误,但我还不够确定。我在 XCode 8.2.1 中使用 Swift 3
更新:我刚刚注意到,即使我的方法解决方案也并不总是有效,编译器有时会决定无论如何都采用更通用的实现。我不确定是什么决定了这一点(我的实际项目更大,提取一个简单的例子有点困难)......所以我可能有一个更普遍的问题:如何可靠地制作泛型类的属性/方法对其类型参数的不同约束做不同的事情?
【问题讨论】: