Swift通用类型变量应符合协议(类型类)

时间:2014-07-23 16:10:28

标签: generics swift protocols type-constraints type-variables

我正在尝试在swift中编写辅助函数,这样可以更方便地进行排序。这是我拥有的和有效的:

someArray.sorted({ someGetter($0) < someGetter($1) })

相反,我想写

someArray.sorted(comparing(someGetter))

我试图像这样定义比较函数

func comparing<A,B : Equatable>(f: A -> B) -> ((A,A) -> Bool) {
    return { f($0) < f($1) }
}

问题是,类型检查器不知道,&#39; B&#39;需要遵守'Equatable&#39;协议。我不知道如何实现这一目标。编译器抱怨&#39; B&#39;不能转换为\“#u; UInt8 \&#39;&#39;,因为它假定两个Ints要通过&#39;&lt;&#39;功能。如果我覆盖&#39;&lt;&#39;例如:

@infix func <(lhs: SomeType, rhs: SomeType) -> Bool {
    return lhs.i < rhs.i
}

然后编译器假定SomeType而不是UInt8。

这是我第二天和Swift一起玩。我希望我的问题不是太愚蠢。我可能还会遇到其他一些错误。

谢谢!

1 个答案:

答案 0 :(得分:1)

我不太确定为什么你需要B Equatable - 因为你要比较这些值,你只需要它们Comparable

func comparing<A, B: Comparable >(f: A -> B) -> (A,A) -> Bool {
    return { f($0) < f($1) }
}

如果执行需要B符合EquatableComparable,则可以使用where子句添加其他约束:

func comparing<A, B: Comparable where B: Equatable>(f: A -> B) -> (A, A) -> Bool {
    return { f($0) < f($1) }
}