Swiftでカスタム初期化子を記述しようとしています。私はこのようなものを持っています:
convenience init(datasource:SomeProtocol) {
assert(datasource != nil, "Invalid datasource")
if(datasource == nil) {
return nil
}
self.init()
}
「return nil」行で次のエラーが発生します。「指定された引数を受け入れる '__conversion'のオーバーロードが見つかりませんでした」
したがって、私が達成しようとしているのは、呼び出し側が有効なデータソースを提供しない場合に、この便利なイニシャライザがnilを返すようにすることです。
ここで何が悪いのですか?
ありがとう
これは、initializers
には実際には値が返されないためです。メソッドが戻り値の型を期待していない場合、nil
を返すことはできません。
実行しようとしていることを実現するには(つまり、クラスにデータソースを強制する)、データソースnotをオプションにします。オプションではない変数mustには値があり(nilにはできません)、初期化する必要があります。
Update: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()
}
これはうまくいくと思いますが、dataSourceを操作している投稿からは明らかではありません。
_class func instOrNil(datasource:A) -> Self? {
// do something with datasource
if datasource.isValid() {
return self()
} else {
return nil
}
}
_
更新Swift
もちろん、init?(...)
からnil
を返すことができます。
_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"
もちろん、これは、イニシャライザがnilを返すスーパークラスを持つ幸運な場合にのみ機能します。したがって、これは一般的な解決策ではありません。