Как бы вы расширили вложенные неограниченные Generics в Swift? - PullRequest
0 голосов
/ 01 мая 2020

Как расширить массив Measurement с, не ограничивая его определенным UnitType?

import Foundation

extension Array where Element == Measurement { // ERROR: Reference to generic type 'Measurement' requires arguments in <...>

    var sum: Double? {
        // `UnitType` doesn’t matter here
        reduce(0, { $0 + $1.value })
    }

}

let array = [
    Measurement(value: 1, unit: UnitVolume.bushels),
    Measurement(value: 2, unit: UnitLength.fathoms),
]

array.sum // expecting `3`

[Обновлено с примером]

1 Ответ

0 голосов
/ 01 мая 2020

Вы можете создать протокол, заставить Measurement соответствовать ему и ограничить коллекцию Element этим протоколом:

protocol Valued { 
    var value: Double { get }
}

extension Measurement: Valued { }

extension Collection where Element: Valued {
    func test() {
        print(self)
    }
    // note that it is pointless to sum different types of units
    var sum: Double {
        reduce(0) { $0 + $1.value }
    }
    // you would need to cast every element to the appropriate unit type before calculating its sum
    var totalLengthInMeters: Double {
        reduce(0) {
            $0 + (($1 as? Measurement<UnitLength>)?.converted(to: .meters).value ?? 0)
        }
    }
} 

let value: Double = 10
let meters: Measurement<UnitLength> = .init(value: value, unit: .meters)
let feet = meters.converted(to: .feet)

let measurements = [meters,feet]
measurements.test()  // [{value 10, unit "m"}, {value 32.80839895013123, unit "ft"}]
// note that it is pointless to sum different types of units
measurements.sum  // 42.80839895013123
// you would need to cast every element to the appropriate unit type before calculating its sum
measurements.totalLengthInMeters  // 20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...