Is there a better way of coping with Swift's nested “if let” “pyramid of doom?”

北城余情 提交于 2019-12-01 03:26:10

问题


Is there a better way of dealing with a chain of optional properties than nested if let statements? I have been advised to use if lets when examining optional properties, which makes sense as it deals with them at compile time rather than run time, but it looks like utter madness! Is there is a better way?

Here is the current "pyramid of doom" I have ended up with, as an example:

( users: [ JSONValue ]? ) in

if let jsonValue: JSONValue = users?[ 0 ]
{
    if let json: Dictionary< String, JSONValue > = jsonValue.object
    {
        if let userIDValue: JSONValue = json[ "id" ]
        {
            let userID: String = String( Int( userIDValue.double! ) )
            println( userID )
        }
    }
}

Post-script

Airspeed Velocity's answer below is the right answer, but you will need Swift 1.2 to use multiple lets separated by commas as he suggests, which only currently runs in XCode 6.3, which is in beta.


回答1:


As commenters have said, Swift 1.2 now has multiple-let syntax:

if let jsonValue = users?.first,
       json = jsonValue.object,
       userIDValue = json[ "id" ],
       doubleID = userIDValue.double,
       userID = doubleID.map({ String(Int(doubleID))})
{
    println( userID )
}

That said, in this instance it looks like you could might be able to do it all via optional chaining in 1.1, depending on what your objects are:

if let userID = users?.first?.object?["id"]?.double.map({String(Int($0))}) {

    println(userID)

}

Note, much better to use first (if this is an array) rather than [0], to account for the possibility the array is empty. And map on the double rather than ! (which would blow up if the value is not double-able).




回答2:


UPDATE for Swift-3 : The syntax has changed :

if let jsonValue = users?.first,
       let json = jsonValue.object,
       let userIDValue = json[ "id" ],
       let doubleID = userIDValue.double,
       let userID = doubleID.map({ String(Int(doubleID))})
{
    println( userID )
}



回答3:


In Swift 2, we have the guard statement.

Instead of:

func myFunc(myOptional: Type?) {
  if let object = myOptional! {
    ...
  }
}

You can do it like this:

func myFunc(myOptional: Type?) {
  guard array.first else { return }
}

Check http://nshipster.com/guard-and-defer/ from NSHipster.



来源:https://stackoverflow.com/questions/29364886/is-there-a-better-way-of-coping-with-swifts-nested-if-let-pyramid-of-doom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!