如何创建适用于每个 class 和结构的中缀运算符?
How can you create an infix operator that applies to every class and struct?
我创建了一个 'configure' 中缀运算符“=>”,它允许我配置内联对象,允许我定义和初始化属性 and/or 在赋值时调用 methods/functions等级.
例如,而不是这个,它需要一个初始化器...
let redSquare = SquareView()
init(){ // Some init somewhere
redSquare.backgroundColor = .red
}
我可以简单地做到这一点...
let redSquare = SquareView() => { [=12=].backgroundColor = .red }
'configure'运算符是这样实现的...
infix operator =>
public protocol Configurable {}
extension Configurable {
public typealias ConfigureDelegate = (Self) -> Void
@discardableResult
public static func => (this:Self, _ delegate:ConfigureDelegate) -> Self {
delegate(this)
return this
}
}
extension NSObject : Configurable {}
Note: You could also implement this as a member function like below, but I prefer the infix operator as it doesn't clutter the . (dot) completion.
public protocol Configurable {}
extension Configurable {
public typealias ConfigureDelegate = (Self) -> Void
@discardableResult
public func configure(delegate:ConfigureDelegate) -> Self {
delegate(self)
return self
}
}
extension NSObject : Configurable {}
如你所见,我已经让 NSObject 符合这个协议,但实际上,这应该可以被任何需要设置不通过初始化器传递的属性的东西使用,或者任何需要 method/function 作为其初始化的一部分被调用。
目前,这意味着我只需要继续在任何地方添加它(对于非基于 NSObject 的项目)...
extension MyStruct : Configurable {}
extension MyClass : Configurable {}
extension MyOtherClass : Configurable {}
这个是不允许的(这真让我烦恼!)
extension AnyObject : Configurable {}
例如,在 C# 中,您可以通过简单地扩展 'object' 来扩展所有内容,因为这是所有内容的基础(具有讽刺意味的是,包括值类型),但看起来 [=42 中没有任何相似之处=].
是否存在,或者我是否只需要继续手动添加这些一致性?
如果您想要的只是一个将闭包应用于您抛出的任何类型的运算符,那么这里的协议并不是真正正确的方法。一个普通的通用运算符(函数)就可以解决问题:
infix operator =>
@discardableResult func => <T>(this: T, _ delegate: (T) -> ()) -> T {
delegate(this)
return this
}
这可以完全按照您概述的方式使用,无需扩展任何内容。
I've created a 'configure' infix operator ...For instance, instead of this, which requires an initializer...
let redSquare = SquareView()
init(){ // Some init somewhere
redSquare.backgroundColor = .red
}
I can simply do this...
let redSquare = SquareView() => { [=11=].backgroundColor = .red }
不需要新的操作员。此功能已存在于 Swift;它被称为闭包(匿名函数):
let redSquare : SquareView = {
let sv = SquareView()
sv.backgroundColor = .red
return sv
}()
在 NSObject 派生的情况下,编译器保证 init()
的存在,您可以使用我的 lend
实用程序压缩符号:
func lend<T> (_ closure: (T)->()) -> T where T:NSObject {
let orig = T()
closure(orig)
return orig
}
因此:
let redSquare = lend { (sv:SquareView) in sv.backgroundColor = .red }
我创建了一个 'configure' 中缀运算符“=>”,它允许我配置内联对象,允许我定义和初始化属性 and/or 在赋值时调用 methods/functions等级.
例如,而不是这个,它需要一个初始化器...
let redSquare = SquareView()
init(){ // Some init somewhere
redSquare.backgroundColor = .red
}
我可以简单地做到这一点...
let redSquare = SquareView() => { [=12=].backgroundColor = .red }
'configure'运算符是这样实现的...
infix operator =>
public protocol Configurable {}
extension Configurable {
public typealias ConfigureDelegate = (Self) -> Void
@discardableResult
public static func => (this:Self, _ delegate:ConfigureDelegate) -> Self {
delegate(this)
return this
}
}
extension NSObject : Configurable {}
Note: You could also implement this as a member function like below, but I prefer the infix operator as it doesn't clutter the . (dot) completion.
public protocol Configurable {}
extension Configurable {
public typealias ConfigureDelegate = (Self) -> Void
@discardableResult
public func configure(delegate:ConfigureDelegate) -> Self {
delegate(self)
return self
}
}
extension NSObject : Configurable {}
如你所见,我已经让 NSObject 符合这个协议,但实际上,这应该可以被任何需要设置不通过初始化器传递的属性的东西使用,或者任何需要 method/function 作为其初始化的一部分被调用。
目前,这意味着我只需要继续在任何地方添加它(对于非基于 NSObject 的项目)...
extension MyStruct : Configurable {}
extension MyClass : Configurable {}
extension MyOtherClass : Configurable {}
这个是不允许的(这真让我烦恼!)
extension AnyObject : Configurable {}
例如,在 C# 中,您可以通过简单地扩展 'object' 来扩展所有内容,因为这是所有内容的基础(具有讽刺意味的是,包括值类型),但看起来 [=42 中没有任何相似之处=].
是否存在,或者我是否只需要继续手动添加这些一致性?
如果您想要的只是一个将闭包应用于您抛出的任何类型的运算符,那么这里的协议并不是真正正确的方法。一个普通的通用运算符(函数)就可以解决问题:
infix operator =>
@discardableResult func => <T>(this: T, _ delegate: (T) -> ()) -> T {
delegate(this)
return this
}
这可以完全按照您概述的方式使用,无需扩展任何内容。
I've created a 'configure' infix operator ...For instance, instead of this, which requires an initializer...
let redSquare = SquareView() init(){ // Some init somewhere redSquare.backgroundColor = .red }
I can simply do this...
let redSquare = SquareView() => { [=11=].backgroundColor = .red }
不需要新的操作员。此功能已存在于 Swift;它被称为闭包(匿名函数):
let redSquare : SquareView = {
let sv = SquareView()
sv.backgroundColor = .red
return sv
}()
在 NSObject 派生的情况下,编译器保证 init()
的存在,您可以使用我的 lend
实用程序压缩符号:
func lend<T> (_ closure: (T)->()) -> T where T:NSObject {
let orig = T()
closure(orig)
return orig
}
因此:
let redSquare = lend { (sv:SquareView) in sv.backgroundColor = .red }