2017-06-12 31 views
0

我在操场上写了一些示例代码,并希望函数返回两个值之间的距离,这两个值符合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子句中使用跨越,一个从ab。根据我的理解,ab将有可能为Stride定义不同的关联类型。此外,我还没有发表任何声明来确保a.Stride == b.Stride,尽管我明白我可以扩展我的where子句来做到这一点。

那么,哪一个会习惯检查与U等价?清楚的是,问题不在于这个特定的代码块,而在于存在这种模糊性的任何情况。

回答

1

ab是相同的类型。如果你想他们是不同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)不会编译,因为他们(ab)是不同的类型,并且Swift3中的distance的定义是public func distance(to other: Self) -> Self.Stride(注意使用Self,其将other限制为与调用该函数的Strideable相同的类型)。总之,尽管你可以制作ab不同的类型,但对于你的应用程序来说,这样做是没有意义的。

作为不能以不同类型的原始发布代码进行调用的进一步证据,请参阅附件 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 

我希望这有助于。

+0

我相信a和b都符合Strideable协议,但它们可能是不同的类型。我测试过用一个Int来调用这个函数,b是一个Double,并且它按照预期编译和运行。 – tnev

+0

请使用我添加到我的答案中的屏幕截图和代码片段再试一次。我相信他们(都是T的)必须是相同的类型。 – Underhill