我刚刚阅读Brent Simmon's post on a problem he is having with Swift,我认为我得到了答案:通用协议一致性。
他遇到的问题是他的协议Value
符合Equatable
。他有另一个协议Smashable
,需要函数valueBySmashingOtherValue
。他有一个结构Bar
,实际上符合Smashable
和Value
。
在采用泛型T
的后续函数中,返回Bar
。 Swift类型系统抱怨'Bar' is not convertible to 'T'
。
以下是我的想法:
protocol Value: Equatable { }
protocol Smashable {
func valueBySmashingOtherValue<T: Value, Smashable>(value: T) -> T
}
struct Bar: Smashable, Value {
func valueBySmashingOtherValue<T: Value, Smashable>(value: T) -> T {
return value;
}
}
func ==(lhs: Bar, rhs: Bar) -> Bool {
return false
}
struct Foo {
func valueBySmashingOtherValue<T: Value, Smashable>(value: T) -> T {
return Bar()
}
}
使通用类型T
符合Value
和Smashable
。 Bar
实际上确实符合这些,所以类型系统应该没问题就可以了。
但它不是。为什么呢?
答案 0 :(得分:0)
虽然Value
确实符合Smashable
和struct NotBar: Smashable, Value {
func valueBySmashingOtherValue<T:Value where T:Smashable>(value: T) -> T {
return value;
}
}
func ==(lhs: NotBar, rhs: NotBar) -> Bool {
return true
}
,但它不是符合这些条件的唯一类型。我可以创建一个新类型(使用最新的Swift语法):
NotBar
如果我将Foo.valueBySmashingOtherValue
的实例传递给NotBar
,那么我希望得到Bar
作为回报。编译器知道这一点,因此它不允许您返回ngCGH
。