如何在 Swift 中声明作为 属性 名称的函数参数
How to declare in Swift a function parameter that is a property name
我想要一个 class 可以在运行时访问另一个 class 中指定的 属性。我猜如果我将闭包或函数作为参数传递是可能的。例如:
class X {
let pointFunction : (Thing) -> (CGPoint)
init(pointFunction : (Thing) -> (CGPoint)) {
self.pointFunction = pointFunction
}
func action(#thing : Thing) {
var p = pointFunction(thing)
...
}
}
和
class func getPosition(thing : Thing) -> CGPoint {
return thing.whereAmI
}
然后在创建X的时候传getPosition
但是是否有一些语法可以让我只传入 whereAmI
作为函数名?然后,在 action
方法中我可以这样做:
thing.pointFunction
你只需要一个Thing->CGPoint
。函数文字和那里的函数一样好:
let x = X(pointFunction: {[=10=].whereAmI})
如果你能保证 whereAmI
是一个 方法 而不是 属性,那么你可以做一些其他的技巧(见 http://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/), 但它只适用于方法。莫名其妙的是,IMO Swift 属性不是方法。如果是,您可以通过 Thing.whereAmI
.
就是说,你必须将你的 init 更改为 Thing -> () -> CGPoint
,无论如何这有点尴尬,或者你必须有两个像这样的 init:
init(pointFunction : (Thing) -> (CGPoint)) {
self.pointFunction = pointFunction
}
convenience init(pointMethod : Thing -> () -> CGPoint) {
self.init(pointFunction: {pointMethod([=11=])()})
}
实际上,{[=16=].whereAmI}
方法在大多数情况下比柯里化方法更容易使用,这正是我在这里推荐的方法。
我想要一个 class 可以在运行时访问另一个 class 中指定的 属性。我猜如果我将闭包或函数作为参数传递是可能的。例如:
class X {
let pointFunction : (Thing) -> (CGPoint)
init(pointFunction : (Thing) -> (CGPoint)) {
self.pointFunction = pointFunction
}
func action(#thing : Thing) {
var p = pointFunction(thing)
...
}
}
和
class func getPosition(thing : Thing) -> CGPoint {
return thing.whereAmI
}
然后在创建X的时候传getPosition
但是是否有一些语法可以让我只传入 whereAmI
作为函数名?然后,在 action
方法中我可以这样做:
thing.pointFunction
你只需要一个Thing->CGPoint
。函数文字和那里的函数一样好:
let x = X(pointFunction: {[=10=].whereAmI})
如果你能保证 whereAmI
是一个 方法 而不是 属性,那么你可以做一些其他的技巧(见 http://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/), 但它只适用于方法。莫名其妙的是,IMO Swift 属性不是方法。如果是,您可以通过 Thing.whereAmI
.
就是说,你必须将你的 init 更改为 Thing -> () -> CGPoint
,无论如何这有点尴尬,或者你必须有两个像这样的 init:
init(pointFunction : (Thing) -> (CGPoint)) {
self.pointFunction = pointFunction
}
convenience init(pointMethod : Thing -> () -> CGPoint) {
self.init(pointFunction: {pointMethod([=11=])()})
}
实际上,{[=16=].whereAmI}
方法在大多数情况下比柯里化方法更容易使用,这正是我在这里推荐的方法。