Сначала обратите внимание, что ваша реализация ==
может быть упрощена до
static func ==(_ lhs: Game, _ rhs:Game) -> Bool {
switch (lhs.correctAnswer, rhs.correctAnswer) {
case (let lhsInt as Int, let rhsInt as Int):
if lhsInt != rhsInt {
return false
}
case (let lhsString as String, let rhsString as String):
if lhsString != rhsString {
return false
}
default:
return false
}
return lhs.description == rhs.description &&
lhs.name == rhs.name &&
lhs.points == rhs.points
}
, так что добавление другого типа ответа просто означает добавление one дополнительного регистра.
Проблема в том, что компилятор не может проверить, что все возможные типы ответов обрабатываются в вашей функции ==
, поэтому этот подход подвержен ошибкам.
Что я на самом деле сделал бы, так это использовалenum Answer
вместо протокола и сделать , что Equatable
:
enum Answer: Equatable {
case int(Int)
case string(String)
}
Обратите внимание, что вам не нужно реализовывать ==
.Начиная с Swift 4.1, компилятор автоматически его синтезирует, см. SE-0185 Синтезирование Equatable и Hashable соответствия .
А теперь Game
упрощается до
struct Game: GameDescriber, Equatable, CorrectAnswer {
var correctAnswer: Answer
var name: String
var description: String
var points: Int
}
, гдекомпилятор также синтезирует ==
с реализацией по умолчанию, которая сравнивает все сохраненные свойства на равенство.
Добавление другого типа ответа просто выполняется путем добавления другого регистра к перечислению:
enum Answer: Equatable {
case int(Int)
case string(String)
case intArray([Int])
}
без дополнительного кода.