2015-03-20 4 views
0

Я борюсь с хорошим шаблоном об обработке нескольких опций в моем коде и соответствующей обработке ошибок.Обработка нескольких необязательных переменных?

Хава посмотреть на следующем примере

func getCoordinates1(pLatitude: Double?, pLongitude: Double?) -> CLLocationCoordinate2D?{ 
    var coord:CLLocationCoordinate2D? 

    if let latitude = pLatitude { 
     if let longitude = pLongitude { 
      coord = CLLocationCoordinate2DMake(lat, long) 
     } 
    } 

    return coord 
} 

Это выглядит хорошо, но в реальном мире, вам может понадобиться обработка ошибок и здесь я ищу хороший способ написания его без дублирования кода :

func getCoordinates2(pLatitude: Double?, pLongitude: Double?) -> CLLocationCoordinate2D? { 
    var coord:CLLocationCoordinate2D? 

    if let latitude = pLatitude { 
     if let longitude = pLongitude { 
      coord = CLLocationCoordinate2DMake(latitude, longitude) 
     } else { 
      // do something to catch the error 
     } 
    } else { 
     // do the same as above (duplicate code) 
    } 

    return coord 
} 

То, что я иногда делаю то, что я использую логическое значение, чтобы следить за ним:

func getCoordinates3(pLatitude: Double?, pLongitude: Double?) -> CLLocationCoordinate2D? { 
    var coord:CLLocationCoordinate2D? 
    var success = false 

    if let latitude = pLatitude { 
     if let longitude = pLongitude { 
      coord = CLLocationCoordinate2DMake(latitude, longitude) 
      success = true 
     } 
    } 
    if !success { 
     // do something to catch the error 
    } 
    return coord 
} 

Или я использую шаблон выхода рано, но я думаю, что это также ошибочная

func getCoordinates4(pLatitude: Double?, pLongitude: Double?) -> CLLocationCoordinate2D? { 

    if let latitude = pLatitude { 
     if let longitude = pLongitude { 
      return CLLocationCoordinate2DMake(latitude, longitude) 
     } 
    } 
    // do something to catch the error 

    return nil 
} 

Конечно это полосатый вниз пример только два дополнительными опциями, но при анализе JSON, намного больше каскадных-если бы необходимо. Надеюсь, идея и проблема понятны.

+1

Это то, что вы ищете http://stackoverflow.com/questions/24118900/using-if-let-with-many-expressions? –

+0

Да, но он будет доступен в Swift 1.2 (и в настоящее время это только бета-версия). – theguy

+0

Просто FYI, шаблон, который вы пытаетесь избежать, называется «The Pyramid Of Doom». –

ответ

2

Как уже упоминалось в комментариях, в Swift 1,2 вы будете в состоянии сделать это:

func getCoordinates2(pLatitude: Double?, pLongitude: Double?) -> CLLocationCoordinate2D? { 
    var coord:CLLocationCoordinate2D? 

    if let latitude = pLatitude, longitude = pLongitude { 
     coord = CLLocationCoordinate2DMake(latitude, longitude) 
    } else { 
     // do something to catch the error 
    } 

    return coord 
} 

Я хотел бы предложить структурировать свой код, чтобы сделать его проще переключиться на этот стиль, когда он станет доступен ,

Попробуйте это:

func getCoordinates2(pLatitude: Double?, pLongitude: Double?) -> CLLocationCoordinate2D? { 
    var coord:CLLocationCoordinate2D? 

    if pLatitude != nil && pLongitude != nil { 
     let latitude = pLatitude! 
     let longitude = pLongitude! 
     coord = CLLocationCoordinate2DMake(latitude, longitude) 
    } else { 
     // do something to catch the error 
    } 

    return coord 
} 

Это имеет ту же семантику и структуру Swift версии 1.2, и когда это становится доступным, вы можете переключиться на более новый синтаксис без необходимости изменения каких-либо отступов.

+0

Спасибо за ваш код. Я вроде бы не хочу этого делать, поскольку у меня такое чувство, что идея опционных - это избегать такого рода nil-тестирования. Но я думаю, что я просто придерживаюсь не-ноль до 1,2 – theguy

0

По существу то, что вы пытаетесь сделать, можно разделить на две группы операций:

  • Первый просто обработка данных (полезная нагрузка)
  • И второй обрабатывает потенциальные ошибки -условию

Работа с условием ошибки всегда одна и та же, то есть, если предыдущая операция вернула ошибку и передала ее вверх по течению, и если до сих пор все было в порядке, обработайте результат и пройдите дальше. Это может быть красиво инкапсулировано в функцию, которая принимает результат и закрытие в качестве ввода и возвращает еще один результат. Думаю, this blog-post от Роба Напира будет вам очень полезен.

Смежные вопросы