Расширение `sum` в последовательности измерений

Вот что у меня есть на данный момент. У него есть как минимум следующие проблемы:

  1. Он дает сбой при использовании в массиве Measurement<UnitType>, когда единицы измерения смешиваются, например, с граммами и миллиграммами.
  2. Использование свойства экземпляра zero не так хорошо, как статическая альтернатива, которая позволяет возвращаемому типу быть типом zero вместо nil для пустой последовательности. Я не могу понять, можно ли этого избежать.

Я использую первое расширение, потому что Sequence.first не существует в текущей версии Swift. ????

import Foundation

public extension Sequence {
    var first: Iterator.Element? {
        return self.first{_ in true}
    }
}

public extension Sequence where Iterator.Element: SummableUsingInstanceZero {
    var sum: Iterator.Element? {
        guard let zero = first?.zero
        else {return nil}

        return self.reduce(zero, +)
    }
}

public protocol SummableUsingInstanceZero {
    static func + (_: Self, _: Self) -> Self

    var zero: Self {get}
}

extension Measurement: SummableUsingInstanceZero {
    public var zero: Measurement {
        return Measurement(
            value: 0,
            unit: unit
        )
    }
}

person Jessy    schedule 09.09.2016    source источник
comment
Вы пытаетесь суммировать последовательность измерений с разными типами единиц измерения?   -  person mixel    schedule 09.09.2016
comment
Иногда. Но только тогда, когда + имеет смысл между ними.   -  person Jessy    schedule 09.09.2016
comment
Свифт 2.2 или 3.0? А пример, где ваш код дает сбой?   -  person Code Different    schedule 10.09.2016


Ответы (1)


Этот вопрос старый, но решение все еще не встроено. Соответствие AdditiveArithmetic — это путь!

import Foundation

extension Measurement: AdditiveArithmetic where UnitType: Dimension {
  public static var zero: Self {
    Self( value: 0, unit: .baseUnit() )
  }

  public static func += (measurement0: inout Self, measurement1: Self) {
    measurement0 = measurement0 + measurement1
  }

  public static func -= (measurement0: inout Self, measurement1: Self) {
    measurement0 = measurement0 - measurement1
  }
}
person Jessy    schedule 28.11.2019