web-dev-qa-db-ja.com

swift-カスタムinitメソッドからstruct default memberwise initを呼び出すことはできますか?

initなしでSwift structを作成すると、次のように、コンパイラで生成されたデフォルトのメンバーごとの初期化子を呼び出すことができます。

_struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate
}
let o = OrderFill(price: 2, qty: 1, timeStamp: someDate)
_

私がやりたいことは、便利なinitメソッドを作成して辞書からデシリアライズし、デフォルトのmemberwise initにチェーンすることです。何かのようなもの

_struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate

    init(dict:[String:AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int
            qty: dict["qty"] as! Int
            timeStamp: try parseDate(dict["ts"] as! String)
    }
}
let o = OrderFill(someDict)
_

しかし、このコードを記述しようとすると、コンパイラー(Xcode 7.2)から「追加の引数 'qty' in call」というエラーが返され、デフォルトのメンバーごとに表示されず、init(dictionary)

独自のメンバーごとのinitを作成することも、単にinit(dictionary)からプロパティを直接割り当てることもできますが、呼び出しをチェーン化できれば素晴らしいことです。これを迅速に行う方法はありますか?

32
Orion Edwards

独自の初期化子を構造体の拡張として追加します。拡張機能は既存の機能を削除できないため、構造体のデフォルトの初期化子を保持します。

struct OrderFill {
    let price: Int
    let qty: Int
    let timeStamp: NSDate
}

extension OrderFill {

    init(dict: [String: AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int,
            qty: dict["qty"] as! Int,
            timeStamp: try parseDate(dict["ts"] as! String)
        )
    }
}

let o = OrderFill(someDict)
79

Apple初期化に関するドキュメント

構造型は、独自のカスタム初期化子を定義していない場合、自動的にメンバーごとの初期化子を受け取ります

そして

値型のカスタム初期化子を定義すると、その型のデフォルトの初期化子(または構造体の場合はメンバーごとの初期化子)にアクセスできなくなることに注意してください。この制約により、誰かが誤って自動イニシャライザーのいずれかを誤って使用することにより、より複雑なイニシャライザーで提供される追加の必須セットアップが回避される状況を防ぐことができます。

したがって、答えは[〜#〜] no [〜#〜]です。カスタム初期化子を提供し、同時にmemberwise初期化子を使用することはできません。

this Swift evolution提案 現在のメンバーごとのイニシャライザの機能を拡張することについて話します。現在の状況の限界とは何かを学ぶために。

9
luk2302