Swift - 引用默认比较函数作为函数参数

Swift - Reference default comparison function as a function parameter

我正在尝试实现一个方便的 Collection.sorted(by: KeyPath) 功能。

到目前为止,如果

func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {
    return sorted { lhs, rhs
        return lhs[keyPath: keyPath] < rhs[keyPath: keyPath]
    }
}

但是如果我想让调用者指定实际的排序逻辑怎么办?我添加了一个回调来执行比较,就像这样(从原始 sorted(_:) 函数签名中获得灵感)。

func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>, _ compare: (T, T) throws -> Bool) rethrows -> [Element] {
    return try sorted { lhs, rhs in
        return try compare(lhs[keyPath: keyPath], rhs[keyPath: keyPath])
    }
}

现在,一切正常,但这意味着调用站点始终必须指定要执行的排序操作。

let sorted = myArray.sorted(by: \.name, <)

我希望它默认为 <,但如何在我的函数签名中默认引用 < 运算符?

实际上可以通过将未应用的 < 函数括在括号 (<) 中作为默认参数来引用它。

func sorted<T: Comparable>(
    by keyPath: KeyPath<Element, T>, 
    _ compare: (T, T) throws -> Bool = (<)
    ) rethrows -> [Element] {
    return try sorted { lhs, rhs in
        return try compare(lhs[keyPath: keyPath], rhs[keyPath: keyPath])
    }
}

但是,当前执行此操作时编译器存在问题。 即使 < 没有抛出,编译器仍会强制您在调用站点使用 try

关于这个的错误报告很久以前就打开了,但仍未解决。如果你 运行 喜欢这个,请点赞:https://bugs.swift.org/browse/SR-1534

此外,正如评论中指出的那样,sorted(by:) 函数实际上是 2 个不同的函数。

一个需要 Comparable 并在内部使用 <,而另一个允许您直接指定排序逻辑,因此不需要 Comparable 一致性。

因此,按 keyPath 进行的这种便捷排序仍然需要 2 个函数。