Как вернуть nil в swift в пользовательском инициализаторе?

Я пытаюсь написать пользовательский инициализатор в Swift. У меня есть что-то вроде этого:

convenience init(datasource:SomeProtocol) {
    assert(datasource != nil, "Invalid datasource")
    if(datasource == nil) {
        return nil
    }
    self.init()
}

строка " return nil "дает мне эту ошибку:"не удалось найти перегрузку для '__conversion', которая принимает предоставленные аргументы"

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

что я здесь делаю не так?

спасибо

4 ответов


потому что initializers на самом деле не возвращает никакого значения. Ты не можешь вернуться!--1--> если метод не ожидает возвращаемого типа.

чтобы достичь того, что вы пытаетесь сделать (т. е. заставить свой класс иметь источник данных), просто сделайте свой источник данных не необязательный. Переменные, которые не являются необязательными должны значение (поэтому не может быть nil) и должен быть инициализирован.


обновление: начиная с Xcode 6.1 beta 1 (доступно в Mac Dev Center), инициализаторы Swift могут быть объявлены для возврата необязательного:

convenience init?(datasource:SomeProtocol) {
    if datasource == nil {
        return nil
    }
    self.init()
}

или неявно развернул необязательно:

convenience init!(datasource:SomeProtocol) {
    if datasource == nil {
        return nil
    }
    self.init()
}

Я думаю, что это сработает, хотя из Вашего сообщения не ясно, где вы работаете с источником данных:

class func instOrNil(datasource:A) -> Self? {
    // do something with datasource
    if datasource.isValid() {
        return self()
    } else {
        return nil
    }
}

Обновление Swift 3

вы можете, конечно, теперь вернуться nil С init?(...):

init?(datasource: A){
    if datasource.isValid() {
        // initialise your properties from datasource
    } else {
        return nil
    }
}

Если суперкласс этого класса является классом Objective-C, и вы знаете, что есть некоторые входные данные, которые заставят его инициализатор вернуться nil, вы можете просто передать этот вход в инициализатор суперкласса, и это заставит ваш инициализатор вернуться nil:

import Foundation
class Foo : NSURL {
  convenience init(x: Int) {
    if x == 42 {
      self.init(string: "http://www.google.com/")
    } else {
      self.init(string: "not a url") // returns nil
    }
  }
}

let a: Foo? = Foo(x: 42)
println(a) // prints "Optional(http://www.google.com/)"
let b: Foo? = Foo(x: 17)
println(b) // prints "nil"

конечно, это работает только в том случае, если вам посчастливилось иметь суперкласс, инициализатор которого вернет ноль. Так что это не общее решение.