广泛的 Swift 扩展协议

Widespread Swift Protocol for Extensions

广泛的扩展协议

Swift4.1,Xcode9.3

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


我的分机:

注:暂时我扩展的“overarching”协议是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 一个值时很有用,现在只需要一行代码即可。

return value.set(to: &variable)

最后一个问题

如何使 .set(to: ) 影响更深远,而不需要它的多个实例?


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


在大多数情况下,我强烈反对这种代码。 "One-line" 代码通常不是 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.

中无法将方法附加到每个可能的类型