通用在哪里条款歧义与相关类型在Swift
问题描述:
我在操场上写了一些示例代码,并希望函数返回两个值之间的距离,这两个值符合Swift中的Strideable协议,以便我可以使用distance(to other: Self) -> Self.Stride
功能。我的执行情况如下:通用在哪里条款歧义与相关类型在Swift
func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U
{
return a.distance(to: b)
}
观察此功能,一段时间后,我意识到,我不知道这是在where子句中使用跨越,一个从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 screenshot,该代码在使用不同类型时会显示错误。
但是,这在工作场所很好。
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
我希望这有助于。
我相信a和b都符合Strideable协议,但它们可能是不同的类型。我测试过用一个Int来调用这个函数,b是一个Double,并且它按照预期编译和运行。 – tnev
请使用我添加到我的答案中的屏幕截图和代码片段再试一次。我相信他们(都是T的)必须是相同的类型。 – Underhill