1

广泛的扩展协议

斯威夫特 4.1,Xcode 9.3

我想知道,Swift 中最重要的协议是什么。我想做一个适用于可以设置的值的扩展。这样做的目的是让编写更多单行代码变得更容易。


我的扩展:

注意:目前,我正在扩展的“总体Equatable”协议是.

extension Equatable {
    @discardableResult public func set(to variable: inout Self) -> Self {
        variable = self
        return self
    }
}

警告:我希望能够.set(to: )用于不符合的值Equatable


用法:

let ten = 10
var twenty = 0

(ten + 10).set(to: &twenty)

print(twenty)
// Prints "20"

当您需要设置和返回值时,这会很有帮助,现在只需要一行代码即可。

return value.set(to: &variable)

最后的问题

如何在.set(to: )不需要多个实例的情况下实现更深远的影响?

  • 例如,如果我为 , , 编写了相同的扩展EquatableCustomStringConvertible对于CVarArg符合所有 3 个协议的许多值,将会有多个相同扩展的建议。
  • 如果这不可能,我可以使用的最佳总体协议是什么?

奖金问题:有没有办法在扩展中做一些与extension Equatable where !(Element: CustomStringConvertible)extension Equatable where !(Element == Int) (使用where谓词进行排除)不相似的事情?


4

1 回答 1

3

在大多数情况下,我强烈反对这种代码。“单行”代码通常不是 Swift 的目标。清晰简洁是一个目标,当他们发生冲突时明确获胜。以这种方式扩展Any(即使它是合法的)通常是一个非常糟糕的主意,因为set(to:)很容易发生冲突。

但在有限的情况下,这可能在单个文件中或用于特殊用途时很有用。在这种情况下,它很容易通过运营商实现。

infix operator -->
private func --> <T>(lhs: T, rhs: inout T) -> T {
    rhs = lhs
    return lhs
}

let ten = 10
var twenty = 0

(ten + 10) --> twenty

print(twenty)
// Prints "20"

做你所描述的更自然的方法是使用你明确遵守的协议。例如:

protocol Settable {}

extension Settable {
    @discardableResult public func set(to variable: inout Self) -> Self {
        variable = self
        return self
    }
}

extension Int: Settable {}
extension String: Settable {}
extension Array: Settable {}
extension Optional: Settable {}

您可以附加Settable到任何对此有用的类型,并且可以在项目中的任何位置(甚至在其他模块中)提供这些扩展。在 Swift 中,没有办法将方法附加到每个可能的类型。

于 2018-05-14T22:49:01.787 回答