![](/img/trans.png)
[英]Access associated type of a custom protocol in a where clause on generic types in Swift
[英]Generic Where Clause Ambiguity with Associated Types in Swift
我在操场上写一些示例代码,想要一个返回两个值之间距离的函数,这两个值均符合Swift中的Strideable协议,因此我可以使用distance(to other: Self) -> Self.Stride
函数。 我的实现如下:
func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U
{
return a.distance(to: b)
}
观察了一段时间后,我意识到我不确定在where子句中使用哪个Stride,即a
或b
中的那个。 据我了解, a
和b
可以为Stride
定义不同的关联类型。 我也没有做任何声明来确保a.Stride == b.Stride,尽管我知道我可以扩展where子句来做到这一点。
那么,哪个会习惯于检查与U
等效性? 明确地说,问题不在于这个特定的代码块,而在于存在这种歧义的任何情况。
a
和b
是相同的类型。 如果希望它们是不同的Strideable
类型,则可以添加另一个符合Strideable
通用参数,以使函数签名如下所示:
func bar<T: Strideable, V: Strideable, U>(_ a: T, to b: V) -> U where T.Stride == U, V.Stride == U {
return a.distance(to: a) //Trivial return statement (see explanation below)
}
尽管上述代码可以编译,但return a.distance(to: b)
不会编译,因为它们( a
和b
)是不同的类型,并且Swift3中distance
的定义是public func distance(to other: Self) -> Self.Stride
(请注意使用的Self
制约other
的相同类型Strideable
在此函数被调用)。 总之,尽管您可以将a
和b
不同的类型,但对于您的应用而言,这样做是没有意义的。
作为无法使用不同类型调用原始发布代码的进一步证据,请参阅随附的Playground屏幕截图 ,其中显示了使用不同类型时的错误。
但是,这在操场上效果很好。
func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U {
return a.distance(to: b)
}
let doubleFoo: Double = 4.5
let intFoo: Double = 4
let g = distanceFrom(doubleFoo, to: intFoo) // gives me a double of -0.5
我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.