Проблема в том, что метод nextInt()
для всех типов GKRandom
возвращает целочисленное значение в диапазоне [INT32_MIN, INT32_MAX]
, что означает, что ваша «нерабочая» реализация next()
возвращает 64-битные значения с старшими 32 битами, равными нулю. Это «нарушает» требование протокола RandomNumberGenerator
, при котором вызовы next()
должны давать равномерно распределенные 64-битные значения.
В более старых выпусках Swift это могло не вызывать проблем, но с реализацией из почти случайного целочисленного генерирования Lemire на 64-битных платформах Intel это приводит к тому, что Random.next(upperBound:)
всегда возвращает ноль:
var gen = SeededGenerator(seed: 234)
print((0..<20).map { _ in Int.random(in: 0..<10, using: &gen) })
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Как следствие, метод shuffle()
вообще не меняет местами элементы массива.
Ваша альтернативная реализация next()
работает, потому что она заполняет как младшие, так и старшие 32 бита 64-битного случайного числа.