2016-08-25 5 views
2

У меня есть протокол, называемый Parameter: Есть ли способ скрыть инициализатор по умолчанию для Swift Struct?

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 
     } 

    } 

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

let calcium = Calcium(value: Double) 

Я также получить инициализатор по умолчанию, созданные структуры:

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

Когда я создаю экземпляры структур, оба инициализатора появляются в пополнении кода кода Xcode. Тем не менее, я не хочу, чтобы параметры name и unit могли быть чем угодно, чем значения по умолчанию, указанные в инициализаторе. Я также попытался присвоить значения по умолчанию для свойств name и unit, где они объявлены внутри структуры, но за пределами инициализатора, требуемого протоколом Parameter.

Есть ли способ инициализации структур путем предоставления значений по умолчанию для параметров name и unit, требуя только параметр value должны быть предоставлены, не имея при этом инициализатора шоу по умолчанию в код завершения всплывающего окна Xcode в?

Единственное, что связано с тем, что у меня есть оба инициализатора, появляется во всплывающем окне завершения кода Xcode, что я не хочу, чтобы кто-то другой создавал структуры и предоставлял значения, отличные от тех, которые я предоставил в инициализаторе, требуемом протоколом Parameter ,

Я понимаю, что я мог бы сделать это с помощью класса, но я пытаюсь понять свое мнение с помощью протокола-ориентированного программирования и использования структур.

ответ

0

Один из способов сделать это:

Мы изменили все переменные опции, и удалены инициализатору с параметрами по умолчанию из протокола. Если unit и value будут иметь значения по умолчанию всегда, клиенту не нужно видеть этот инициализатор.

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 
    } 

} 

В самой структуре, мы добавили частный инициализатор, который вызывается из пользовательского инициализаторе требуется только один параметр.

И вы получите только один инициализатор во всплывающем окне завершения Xcode. image

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