Cocoa 在Swift中扩展Bool以获得乐趣和新的控制结构

Cocoa 在Swift中扩展Bool以获得乐趣和新的控制结构,cocoa,swift,swift-extensions,Cocoa,Swift,Swift Extensions,我正在玩Swift扩展,在尝试扩展Bool时,我的头撞到了一个奇怪的bug: typealias Task = ()->() extension Bool{ func untilFalse(task: Task){ while !self {println(self); task()} } } var i = 2 (i < 1).untilFalse{ println(i) println("\(i) bottles of bee

我正在玩Swift扩展,在尝试扩展Bool时,我的头撞到了一个奇怪的bug:

typealias Task = ()->()
extension Bool{
    func untilFalse(task: Task){

        while !self {println(self); task()}
    }
}

var i = 2

(i < 1).untilFalse{
    println(i)
    println("\(i) bottles of beer on the wall, \(i) bottles of beer.")
    i--
    println("Take one down and pass it around, \(i) bottles of beer on the wall.")
}
typealias任务=()->()
扩展布尔{
func untilFalse(任务:任务){
while!self{println(self);task()}
}
}
变量i=2
(i<1)。直到最后{
println(i)
println(“\(i)瓶啤酒挂在墙上,\(i)瓶啤酒。”)
我--
println(“拿下一瓶,把它传来传去,\(i)墙上有几瓶啤酒。”)
}
出于某种原因,循环一直在继续,甚至在
布尔表达式变为
真之后也是如此


有什么想法吗?

问题是表达式
i<1
将被计算一次,结果是
为false
。不会持续重新评估。要实现这一点,您必须将其替换为函数或闭包

如果确实需要,可以按如下方式重新编写代码:

typealias Task = ()->()
typealias BooleanExpression = () -> Bool

infix operator *** {}

func *** (b: BooleanExpression, t: Task) {
  while !b() { t() }
}

var i = 2

let exp: BooleanExpression = { i < 1 }
exp *** {
  println(i)
  println("\(i) bottles of beer on the wall, \(i) bottles of beer.")
  i--
  println("Take one down and pass it around, \(i) bottles of beer on the wall.")
}
typealias任务=()->()
typealias BooleanExpression=()->Bool
中缀运算符***{}
func***(b:boolean表达式,t:Task){
而!b(){t()}
}
变量i=2
设exp:booleanpression={i<1}
出口**{
println(i)
println(“\(i)瓶啤酒挂在墙上,\(i)瓶啤酒。”)
我--
println(“拿下一瓶,把它传来传去,\(i)墙上有几瓶啤酒。”)
}

但那真是太难看了

与科林的表达式相同,但在自动闭包的基础上,您可以使用:

typealias Task = ()->()

infix operator *** {}
func ***(expression:@autoclosure ()->Bool, task:Task) {
    while !expression() {
        task()
    }
}

var i = 2

(i < 1) *** {
    println(i)
    println("\(i) bottles of beer on the wall, \(i) bottles of beer.")
    i--
    println("Take one down and pass it around, \(i) bottles of beer on the wall.")
}
typealias任务=()->()
中缀运算符***{}
func***(表达式:@autoclosure()->Bool,任务:task){
while!表达式(){
任务()
}
}
变量i=2
(i<1)***{
println(i)
println(“\(i)瓶啤酒挂在墙上,\(i)瓶啤酒。”)
我--
println(“拿下一瓶,把它传来传去,\(i)墙上有几瓶啤酒。”)
}
这就简化了一些事情。当然,自然的语法是只使用如下内容:

func untilFalse(expression:@autoclosure ()->Bool, block:()->()) {
    while(!expression()) {
        block()
    }
}

var i = 2
untilFalse(i < 1) {
    println("\(i) bottles of beer on the wall, \(i) bottles of beer.")
    i--
    println("Take one down and pass it around, \(i) bottles of beer on the wall.")
}
func untilFalse(表达式:@autoclosure()->Bool,block:()->()){
而(!expression()){
块()
}
}
变量i=2
直到最后(i<1){
println(“\(i)瓶啤酒挂在墙上,\(i)瓶啤酒。”)
我--
println(“拿下一瓶,把它传来传去,\(i)墙上有几瓶啤酒。”)
}
它建立在autoclosure和尾部块语法的基础上,似乎为语言添加了一种新的语句类型