扩展的广泛Swift协议

时间:2018-05-14 21:25:24

标签: swift protocols where-clause swift-extensions inout

广泛的扩展协议

Swift 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: )更远,而不需要多个实例?

  • 例如,如果我为EquatableCustomStringConvertibleCVarArg编写了相同的扩展名,那么对于符合所有这三个值的许多值,会有多个相同扩展名的建议协议。
  • 如果无法做到这一点,我可以使用的最佳总体协议是什么?

加分问题: 扩展程序中有一种方法可以执行与extension Equatable where !(Element: CustomStringConvertible)extension Equatable where !(Element == Int)不同的操作(使用where谓词用于排除目的)

1 个答案:

答案 0 :(得分: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中为每种可能的类型附加方法。