Swift 4 - Используйте типы с плавающей запятой с `random (: in)` и целочисленные типы с `random (: in)` в одной универсальной функции - PullRequest
0 голосов
/ 03 октября 2018

У меня есть расширения для 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())
    }
}
...