Swift中关联类型的子句歧义的通用

时间:2017-06-12 23:34:21

标签: swift generics where associated-types

我在操场上编写了一些示例代码,并且想要一个返回两个值之间距离的函数,这两个值都符合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,ab。根据我的理解,ab可以为Stride定义不同的关联类型。此外,我还没有发表任何声明来确保a.Stride == b.Stride,虽然我知道我可以扩展我的where子句来这样做。

那么,哪一个会用来检查U的等价性?要清楚,问题不在于这个特定的代码块,而在于存在这种歧义的任何情况。

1 个答案:

答案 0 :(得分: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的定义是{{ 1}}(注意使用public func distance(to other: Self) -> Self.StrideSelf限制为与调用此函数的other相同的类型。总而言之,尽管您可以为Strideablea设置不同的类型,但对于您的应用程序而言,这样做是没有意义的。

作为无法使用不同类型调用原始发布代码的进一步证据,请参阅附件 Playground screenshot在使用不同类型时显示错误。

然而,这在操场上运作良好。

b

我希望这会有所帮助。