3

私はと呼ばれるプロトコルを持っていますParameter:

protocol Parameter {

    var name: String { get }
    var unit: Unit? { get }
    var value: Double { get }

    init(name: String, unit: Unit?, value: Double)

}

また、以下に準拠する 16 の構造体がありますParameter

struct Calcium: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Calcium", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Alkalinity: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Alkalinity", unit: Unit? = Unit(symbol: "ppm CaCO3"), value: Double) {
        self.name = name
       self.unit = unit
        self.value = value
    }

} 

struct Salinity: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Salinity", unit: Unit? = Unit(symbol: "SG"), value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

} 

struct Temperature: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Temperature", unit: Unit? = UnitTemperature.fahrenheit, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct PH: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "pH", unit: Unit? = nil, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Magnesium: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Magnesium", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Phosphate: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Phosphate", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Ammonia: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Ammonia", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Silica: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Silica", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Iodine: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Iodine", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Nitrate: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Nitrate", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Nitrite: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Nitrite", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Strontium: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Strontium", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct ORP: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "ORP", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

struct Boron: Parameter {

    var name: String
    var unit: Unit?
    var value: Double

    init(name: String = "Boron", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

    struct Iron: Parameter {

        var name: String
        var unit: Unit?
        var value: Double

        init(name: String = "Iron", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
            self.name = name
            self.unit = unit
            self.value = value
        }

    }

ご覧のとおり、すべての構造体が同じ初期化子を実装しています。イニシャライザでは、プロトコルに必要な 3 つのパラメータのうち 2 つにデフォルト値を指定しParameterます。これにより、次のイニシャライザが得られます。

let calcium = Calcium(value: Double)

また、構造体によって作成されたデフォルトの初期化子も取得します。

let calcium = Calcium(name: String, unit: Unit?, value: Double)

構造体のインスタンスを作成すると、両方の初期化子が Xcode のコード補完ポップオーバーに表示されます。nameただし、パラメータとunitパラメータがイニシャライザで提供されるデフォルト値と異なるものになることは望ましくありません。また、構造体の内部で宣言されているが、プロトコルで必要な初期化子の外部で宣言されているnameおよびプロパティにデフォルト値を割り当てようとしました。unitParameter

Xcodeのコード補完ポップアップにデフォルトのイニシャライザを表示せずに、nameおよびunitパラメータにデフォルト値を指定し、パラメータのみを指定して構造体を初期化する方法はありますか?value

Parameter両方の初期化子を Xcode のコード補完ポップアップに表示することに関する唯一の懸念は、他の誰かが構造体を作成し、プロトコルで必要な初期化子で提供した値以外の値を提供したくないということです。

クラスでそれができることはわかっていますが、プロトコル指向のプログラミングと構造体の使用について理解を深めようとしています。

4

1 に答える 1

0

それを行う1つの方法:

すべての変数をオプションに変更し、プロトコルからデフォルト パラメータを持つイニシャライザを削除しました。unitvalueがデフォルト値を always持つ場合、クライアントがこのイニシャライザを参照する必要はありません。

protocol Parameter {
    var name: String? { get }
    var unit: Unit? { get }
    var value: Double? { get }
    //init(name: String, unit: Unit?, value: Double)
    init(value: Double)
}

そして、構造を次のように変更します。

struct Calcium: Parameter {

    var name: String? = nil
    var unit: Unit? = nil
    var value: Double? = nil

    init(value: Double) {
        self.init(name: "Calcium", unit: UnitDispersion.partsPerMillion, value: value)
    }

    private init(name: String, unit: Unit, value: Double) {
        self.name = name
        self.unit = unit
        self.value = value
    }

}

構造体自体に、1 つのパラメーターのみを必要とするカスタム イニシャライザーから呼び出されるプライベート イニシャライザーを追加しました。

また、Xcode の完了ポップアップにはイニシャライザが 1 つしかありません。 画像

于 2016-10-12T09:16:32.027 に答える