假设我有一个班级:
class Test {
func someMethod() {}
init(closure:(Test)->Void) {
closure(self)
}
}
我可以在另一个类(1)
的另一个方法中调用initTest {
$0.someMethod()
}
或像这样(2)
Test { t in
t.someMethod()
}
是否有任何可能的解决方案可以在没有“$ 0”或“t”的情况下编写完全相同的内容?我想得到这段代码(3)
Test {
someMethod()
}
行为必须与(1)或(2)完全相同。
有可能吗?也许不是关闭,而是使用其他一些Swift功能?
我想做类似Kotlin类型安全构建器的事情:http://kotlinlang.org/docs/reference/type-safe-builders.html
答案 0 :(得分:1)
不确定你追求的是什么,但我想知道这一点点伏都教对你有用:
class Test {
var name : String
init(_ name:String) {self.name = name}
func someMethod() { println("Hi, my name is \(name)") }
}
let f = Test.someMethod
let t1 = Test("matt")
let t2 = Test("bealex")
f(t1)() // Hi, my name is matt
f(t2)() // Hi, my name is bealex
要点是f(t1)
本身就是一个函数,在调用时,会将someMethod
发送到实例t1
。你可能会从中获得一些好处。
答案 1 :(得分:1)
我相信在Swift中这是不可能的,因为swift缺少某种动态扩展功能功能。
在swift中,扩展的唯一方法是定义一个新函数(或其他),如:
extension Type {
func function() {}
}
据我所知,没有可能动态定义扩展。
所以我们真正缺少的是这样的:(下一版Swift的愿望清单?)
以下代码不起作用,示例如何使用
class Test {
var aVar = 0
func someMethod() {}
// Param declares function as an extension on type Test!
class func initialize(closure: Test.()->Void) -> Test {
let instance = Test()
instance.closure()
return instance
}
}
// And it would be possible to do:
Test.initialize {
self.someMethod()
aVar = 1234 // With or without self, with or without self...
}
再次,不工作。但是哦,它会有多好......
更新:代码现在有点固定。
答案 2 :(得分:0)
您必须满足类型检查器。所以typechecker希望你写一个Test -> Void
的闭包。如果您不使用Test
参数,则可以忽略它:
Test { _ in someAnotherMethod() }
编辑:我完全误解了你的问题@bealex。现在我有另一个解决方案,但它很难看,它有一些局限性。这是代码
class Test {
init (_ f: Test -> () -> Void) {
f(self)()
}
func doSomething() {
println("Hello world")
}
}
let test = Test(Test.doSomething)
这仅适用于不采用(或更确切地说void
)参数的方法。有关如何工作:Swift实例方法是curried函数,第一个参数是self
。 Link
例如,采用一个参数的方法,我们可以编写交换方法来交换函数的参数顺序。
func swap<A, B, C>(f: A -> B -> C) -> B -> A -> C {
return { b in { a in f(a)(b)} }
}
现在我们可以写
class Test {
init (_ f: Test -> Void) {
f(self)
}
func doSomethingWithNumber(number: Int, str: String) {
println("Hello planet \(number), \(str)")
}
}
let test = Test(swap(Test.doSomethingWithNumber)(10, "Greetings"))
但这比使用普通$0 and $1
更加冗长。无论如何,这是另一种观点。