2015-11-18 2 views
3

Каков наилучший способ обработки init, который может завершиться ошибкой в ​​Swift? Например, вы создаете экземпляр класса, который зависит от определенного ресурса, который может быть недоступен.Ошибки в инициализаторах Swift

Видимо у нас есть 2 варианта:

  • подлежащий передаче на поруки инициализации, который возвращает ноль (какао способ)
  • инициализации, который выдает ошибку

Ниже

enum ThingError: ErrorType{ 
    case crap 
} 
class Thing { 
    init(c: Int) throws{ 
     if c < 0 { 
      throw ThingError.crap 
     } 
    } 
} 



var c = try Thing(c: 3) 

do{ 
    var d = try Thing(c: -4) 
}catch{ 
    print("oh vey!") 
} 

Есть ли рекомендуемый способ сделать это? Второй вариант выглядит более «Swifty» ...

ответ

6

Ничего изначально не лучше или быстрей.

Лично я нахожу throws инициализаторы огромную боль. Я бы скорее получил неудачный инициализатор return nil, потому что тогда я могу выполнить свою инициализацию с помощью guard let вместо того, чтобы обернуть вещи в do/catch и разобраться с полученными проблемами. Ваш код иллюстрирует проблему; ваш var d «застрял» внутри области do. Я бы сказал так:

guard let d = Thing(c:-4) else {return} 
// now d is unwrapped and in scope! 

... чем это (то, что вы должны сказать):

do { 
    var d = try Thing(c: -4) 
} catch { 
    print("oh vey!") 
} 
// and here there is no `d`, so _now_ what? 

С другой стороны, бросая ошибку предлагает возможность отправить сообщение, т.е. быть коммуникативным о том, что пошло не так. Вы не можете сделать это с помощью простого инициализатора init?; он работает, или он терпит неудачу, и это все, что знает вызывающий.

+0

«Сколько раз вы сталкиваетесь с init, который может терпеть неудачу несколькими способами» Все время @Grimxn. Я думал о 'initWithContentsOfURL: encoding: error:' мгновенно, и есть много и много других. Именно поэтому в Objective-C такие методы имеют параметр «error:». Этот параметр говорит вам, что мы не смогли. – matt

+0

", что большинство inits терпят неудачу в ноль или один путь, а одиночные отказы должны использовать failable ..." И это, @Grimxn, я считаю, это то, что мой ответ сказал _, нет? – matt

+0

Вы правы - я ничего здесь не добавляю, кроме как документируя свое собственное медленное понимание. Добавьте свои комментарии к ответам, и я удалю свои комментарии. – Grimxn

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