generics - Swift 通用类型变量应遵守协议(protocol)(类型类)

标签 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) }
}

问题是,类型检查器不知道“B”需要遵守“Equatable”协议(protocol)。我不知道如何实现这一目标。编译器提示 '\'B\' 不可转换为\'UInt8\'',因为它假定两个 Int 由 '<' 函数进行比较。如果我覆盖 '<' 例如:

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

然后编译器采用 SomeType 而不是 UInt8。

这是我使用 Swift 的第二天。我希望我的问题不是太愚蠢。我可能还会犯很多其他错误。

谢谢!

最佳答案

我不太清楚为什么你需要 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) }
}

关于generics - Swift 通用类型变量应遵守协议(protocol)(类型类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24915626/

相关文章:

java - 无法将 List<SomeClass<SomeClass 的边界类型的子级>> 添加到 List<SomeClass<?>>

java - Class<V> 可以对泛型类型进行多重限制吗?

swift - 仅类协议(protocol)作为具有 AnyObject 约束的关联类型的类型别名

java - 从输入流解析自定义二进制协议(protocol)

swift - self 协议(protocol)的行为

Swift 在泛型和协议(protocol)中使用 Self(在方法级别没有初始化)

java - 为什么 java.util.Map.get(...) 不是通用的?

c# - 如何确定 macOS 应用程序是否是通过 url 启动的

ios - 使用 GeoFire 检查附近是否没有位置

ios - 如何在项目中添加自定义 iOS 框架的引用(而不是复制)