在任意操作中快速选择链接?

Gra*_*smo 5 optional chaining ios swift

Apple提供了一个简洁的可选链接示例

class Person {
  var residence: Residence?
}

class Residence {
  var numberOfRooms = 1
}

let john = Person()

if let roomCount = john.residence?.numberOfRooms {
  println("John's residence has \(roomCount) room(s).")
} else {
  println("Unable to retrieve the number of rooms.")
}
Run Code Online (Sandbox Code Playgroud)

想象一下尝试用一些算术运算来调整条件.这会导致编译器错误,因为模运算符不支持选项.

if john.residence?.numberOfRooms % 2 == 0 { 
  // compiler error: Value of optional type Int? not unwrapped
  println("John has an even number of rooms")
} else {
  println("John has an odd number of rooms")
}
Run Code Online (Sandbox Code Playgroud)

当然,您总是可以执行以下操作,但它缺乏可选链接的简单性和简洁性.

if let residence = john.residence {
  if residence.numberOfRooms % 2 == 0  {
    println("John has an even number of rooms")
  }else{
    println("John has an odd number of rooms")
  }
} else {
  println("John has an odd number of rooms")
}
Run Code Online (Sandbox Code Playgroud)

是否有任何Swift语言功能可以提供更好的解决方案?

Gra*_*smo 0

我能想到的最好的办法是一个名为 omap(可选映射)的可选扩展。

extension Optional{
  func omap<K:Any>(optionalBlock:(T)->(K?))->K?{
    if self{
      return optionalBlock(self!)
    }
    return nil
  }
}
Run Code Online (Sandbox Code Playgroud)

与 map 类似,omap 只是将可选值的实例返回给所提供的闭包,但会适当地处理 nil 情况。

这允许您将可选值与任意操作链接起来,如下所示:

if (john.residence.omap{r in r.numberOfRooms % 2 == 0}){
  println("John has an even number of rooms")
} else {
  println("John has an odd number of rooms")
}
Run Code Online (Sandbox Code Playgroud)

请参阅:https ://gist.github.com/Grantismo/3e1ba0412e911dfd7cfe

  • 我的印象是任何答案都应该包含在答案部分,即使它是由提问者提供的。请参阅:http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/。我也不相信我的解决方案是最好的,所以我希望其他人能提供他们的想法。 (2认同)