我对Range
和ClosedRange
进行了扩展(请参见下文),使它们可以用于生成随机浮点值。我希望它们也能够在相同的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())
}
}