Скажем, у меня есть два структур, которые соответствуют протоколу,Swift операторы протоколов
protocol NumberType {
var doubleValue: Double { get }
}
struct Rational: NumberType {
let numerator: Int
let denominator: Int
var doubleValue: Double { get { return Double(numerator)/Double(denominator) } }
}
struct FixedPoint: NumberType {
let value: Double
var doubleValue: Double { get { return value } }
}
И я хочу, чтобы определить арифметические операторы для NumberType
, что в свою очередь, возвращение NumberType
с.
func *(lhs: NumberType, rhs: NumberType) -> NumberType { return FixedPoint(lhs.doubleValue * rhs.doubleValue) }
Но я также хочу, чтобы добавить более конкретные операторы так, когда оба Rational
s, я возвращаю Rational
.
func *(lhs: Rational, rhs: Rational) -> NumberType { return Rational(...) }
Есть ли более элегантный способ сделать это, чем иметь одну суперфункцию для каждого оператора, который выполняет все проверки типов?
редактируетВы должны быть в состоянии умножить FixedPoint рациональными, так как оба они соответствуют NumberType.
Стратегия перегрузки не будет работать, потому что если я a * b * c
, где все значения являются Rational
, результат a * b
является NumberType
, и поэтому (a * b) * c
вернется к использованию универсального оператора NumberType
умножения. Я потеряю свою точность здесь.
Я не беспокоили о возможности умножать на Doubles
, Ints
и т.д.
Дальнейшие редактирует
Это не правильно считать, что наиболее общий случай всегда возвращает FixedPoint
. Я показываю основное использование здесь, но если у вас есть FixedPoint
, равный 0
, а еще один Rational
, и вы хотели добавить их, вполне возможно, что вы можете получить Rational
в своем общем случае.
Фиксированная точка должна быть способна умножаться на рациональную, используя самую общую форму, NumberType * NumberType. –
Извините, исправить пример. Самая общая версия возвращает FixedPoint. –
Надеюсь, вы поймете, что ваша реализация FixedPoint' использует тип с плавающей точкой для хранения значения;) – Hamish