2014-07-23 52 views
1

我想在swift中编写一个帮助函数,它允许更方便地进行排序。以下是我有什么工作: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) } 
} 

的问题是比较功能,类型检查者不知道,'B'需要符合'可衡量'协议。我不知道如何实现这一点。编译器抱怨'\'B \'不能转换为\'UInt8 \',因为它假定两个Ints被'<'函数比较。如果我用例如:

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

覆盖“<”,那么编译器假定SomeType而不是UInt8。

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

谢谢!

回答

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) } 
} 
+0

非常感谢您!是的,那确实是错误的协议。你碰巧知道,为什么Comparable只定义了<=, > =和>而不是<?我从另一种语言了解到,一个操作员可以被其他人表达。你知道Swift是否也支持协议中某些方法的默认实现?也可能有一个<需要Comparable协议的通用定义,但我只找到一个。同样对于我的类,SomeType现在实现了Comparable,但我不需要提供更多的实现。 '<' - 实现似乎已经足够了。你碰巧知道为什么? – thetrutz

+0

如果你已经定义了足够多的操作符,编译器可以找出其他的。我猜'SomeType'实现了'Equatable',对吧?如果编译器知道'<'和'==',它可以自己将'<=', '> ='和'>'放在一起。 –