广泛的 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: )
影响更深远,而不需要它的多个实例?
- 例如,如果我为
Equatable
、CustomStringConvertible
、CVarArg
编写相同的扩展名,对于符合所有 3 个值的许多值,将有多个相同扩展名的建议这些协议。
- 如果这不可能,我可以使用的最好的总体协议是什么?
奖金问题: 有没有办法在扩展中做一些与 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.
中无法将方法附加到每个可能的类型
广泛的扩展协议
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: )
影响更深远,而不需要它的多个实例?
- 例如,如果我为
Equatable
、CustomStringConvertible
、CVarArg
编写相同的扩展名,对于符合所有 3 个值的许多值,将有多个相同扩展名的建议这些协议。 - 如果这不可能,我可以使用的最好的总体协议是什么?
奖金问题: 有没有办法在扩展中做一些与 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.