简体   繁体   English

如何在 Bound 是通用的地方扩展 ClosedRange

[英]How to extend ClosedRange where Bound is generic

For some additional functionality I'd like to extend ClosedRange where the Bounds are Measurement .对于一些附加功能,我想扩展ClosedRange ,其中 Bounds 是Measurement

extension ClosedRange where Bound == Measurement

…obviously isn't working as Measurement as a generic type requires an <> argument. …显然不能像Measurement那样工作,因为泛型类型需要<>参数。

extension ClosedRange where Bound == Measurement<UnitType> // Cannot find type 'UnitType' in scope

Concatenating where s doesn't seem to work either.连接where s 似乎也不起作用。

I am out of ideas.我没主意了。

The only thing I found to be working is:我发现唯一有效的是:

extension ClosedRange where Bound == Measurement<UnitLength> {

    func unit() -> UnitLength {
        return lowerBound.unit
    }

}

let range = Measurement(value: 5, unit: UnitLength.meters)...Measurement(value: 15, unit: UnitLength.meters)
range.unit().symbol // m

But I don't want to copy and paste this for all unit types.但我不想为所有单位类型复制和粘贴它。 Isn't this what generics are there for after all?毕竟这不是 generics 的用途吗?

This comes close to what I want, doesn't work though:这接近我想要的,但不起作用:

extension ClosedRange where Bound == Measurement<UnitType> { // Cannot find type 'UnitType' in scope

    func unit() -> UnitType { // Cannot find type 'UnitType' in scope
        return lowerBound.unit
    }

}

let range = Measurement(value: 5, unit: UnitLength.meters)...Measurement(value: 15, unit: UnitLength.meters)
range.unit

EDIT:编辑:

Thanks Dávid Pásztor for the answer.感谢 Dávid Pásztor 的回答。 I would like to extend my question:我想扩展我的问题:

How can I add a function for Measurement s with UnitType s that inherit from Dimension ?如何使用继承自Dimension的 UnitType 为Measurement添加UnitType

extension ClosedRange {

    func convertedLowerBound<UnitType>(to unit: UnitType) -> Double where Bound == Measurement<UnitType> {
        lowerBound.converted(to: unit).value // Referencing instance method 'converted(to:)' on 'Measurement' requires that 'UnitType' inherit from 'Dimension'
    }

}

let range = Measurement(value: 5, unit: UnitLength.meters)...Measurement(value: 15, unit: UnitLength.meters)
range.convertedLowerBound(to: .centimeters)
Referencing instance method 'converted(to:)' on 'Measurement' requires that 'UnitType' inherit from 'Dimension'

Yes, I could just call range.lowerBound.converted(to: .centimeters) .是的,我可以打电话range.lowerBound.converted(to: .centimeters) The exact functionality I plan to implement doesn't work like this though.我计划实现的确切功能不是这样工作的。

You need to make the extension itself generic, however that's not yet supported by Swift.您需要将扩展本身设为通用,但 Swift 尚不支持。 You can make the function itself generic though.不过,您可以使 function 本身具有通用性。

extension ClosedRange {
    func unit<UnitType>() -> UnitType where Bound == Measurement<UnitType> {
        lowerBound.unit
    }

    func convertedLowerBound<UnitType: Dimension>(to unit: UnitType) -> Double where Bound == Measurement<UnitType> {
        lowerBound.converted(to: unit).value
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM