Swift 4 –在单个泛型函数中使用带有“ random(:in)”的浮点类型和带有“ random(:in)`的整数类型

时间:2018-10-03 14:29:16

标签: swift generics swift4 protocols

我对RangeClosedRange进行了扩展(请参见下文),使它们可以用于生成随机浮点值。我希望它们也能够在相同的Randomizable协议下生成随机整数值,而无需区分方法。具有random(in:)的整数类型都是FixedWidthInteger

这很简单,如果泛型where子句中允许析取:

where (Bound: BinaryFloatingPoint && Bound.RawSignificand: FixedWidthInteger)
       || Bound: FixedWidthInteger

但是,出于深思熟虑的原因,Swift仅允许连接。

是否有某种方法可以制作where子句(可能通过引入其他协议来选择预期的类型)?

其他看似无路可走的地方包括两次采用了不重叠where子句的协议(不允许)。

如果没有其他发现,一个明显的解决方法是为浮点数和整数制定单独的协议,但这恰好可以复制所有我觉得不合适的代码。

有关总体目标的更多背景信息,请参见此问题:Swift 4 -- Challenge trying to use Generics to reduce formulaic code

import SceneKit

public protocol Randomizable {
    associatedtype Value
    func random() -> Value
}

extension ClosedRange : Randomizable where Bound: BinaryFloatingPoint,
                                           Bound.RawSignificand: FixedWidthInteger {
    public typealias Value = Bound
    public func random() -> Value {
        return Value.random(in: self)
    }
}

extension Range : Randomizable where Bound: BinaryFloatingPoint,
                                     Bound.RawSignificand: FixedWidthInteger {
    public typealias Value = Bound
    public func random() -> Value {
        return Value.random(in: self)
    }
}

extension SCNVector3 {
    public static func random<R1: Randomizable, R2: Randomizable, R3: Randomizable>
      (_ xr: R1, _ yr: R2, _ zr: R3) -> SCNVector3
      where R1.Value == CGFloat, R2.Value == CGFloat, R3.Value == CGFloat {
        return SCNVector3(xr.random(), yr.random(), zr.random())
    }
}

0 个答案:

没有答案