У меня есть расширения для Range
и ClosedRange
(см. Ниже), которые позволяют использовать их для генерации случайных значений с плавающей запятой.Я хотел бы, чтобы они также могли генерировать случайные целочисленные значения по одному и тому же рандомизированному протоколу без дифференциации метода.Целочисленные типы, которые имеют random(in:)
, являются FixedWidthInteger
.
. Это было бы просто, если бы были разрешены дизъюнкции в общих выражениях where:
where (Bound: BinaryFloatingPoint && Bound.RawSignificand: FixedWidthInteger)
|| Bound: FixedWidthInteger
Но, по вдумчивым причинам, только Swiftпозволяет союзы.
Есть ли какой-нибудь способ сделать предложение where, возможно, путем введения другого (ых) протокола (ов), который выбирает предполагаемые типы?
Другие кажущиеся тупики включают в себя принятый протокол дважды с неперекрывающиеся операторы where (не допускаются).
Если больше ничего не обнаруживается, очевидным обходным решением является создание отдельных протоколов для чисел с плавающей запятой и целых чисел, но это точно копирует весь код, который не кажется правильнымme.
См. этот вопрос для получения дополнительной информации об общей цели: Swift 4 - Испытание с использованием универсальных методов для сокращения кода формулы .
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())
}
}