Есть ли способ скрыть инициализатор по умолчанию для Swift Struct?
У меня есть протокол под названием 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
}
}
Как видите, все структуры реализуют один и тот же инициализатор. В инициализаторе я предоставляю значения по умолчанию для двух из трех параметров, требуемых 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
протокол.
Я понимаю, что мог бы сделать это с помощью класса, но я пытаюсь правильно сориентироваться в программировании на основе протоколов и использовании структур.
1 ответ
Один из способов сделать это:
Мы изменили все переменные на необязательные и удалили инициализатор с параметрами по умолчанию из протокола. Если 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.