【问题标题】:Extending Bool for fun and new control structures in Swift在 Swift 中扩展 Bool 以获得有趣和新的控制结构
【发布时间】:2014-09-15 20:38:58
【问题描述】:

我在玩 Swift 扩展,在尝试扩展 Bool 时遇到了一个奇怪的错误:

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.")
}

由于某种原因,即使在boolean 表达式变为true 之后,循环也会继续进行。

对可能发生的事情有任何想法吗?

【问题讨论】:

    标签: cocoa swift swift-extensions


    【解决方案1】:

    问题是表达式i &lt; 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.")
    }
    

    但这实在是太丑了!

    【讨论】:

      【解决方案2】:

      与 Colin 的表达方式相同,但在此基础上使用自动关闭,您可以使用:

      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.")
      }
      

      这稍微简化了一些事情。当然,自然的语法就是使用类似的东西:

      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.")
      }
      

      它建立在自动关闭和尾随块语法的基础上,似乎为语言添加了一种新的语句类型

      【讨论】:

        猜你喜欢
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-11
        • 1970-01-01
        • 2017-07-20
        相关资源
        最近更新 更多