самый короткий код для создания массива случайных чисел в Swift?

Я хочу создать массив случайных чисел (Int, Int32)

Я пробовал следующее:

map(1...1000) { arc4random() } 

но он возвращает следующую ошибку:

error: type 'ClosedInterval<T>' does not conform to protocol 'SequenceType'

Что я делаю неправильно?


По какой-то причине небольшая настройка моих первых попыток работает нормально.

map(1...1000) { $0 - $0 + arc4random() }

Проблема в том, что я не понимаю, почему этот измененный подход работает и почему первоначальный подход не работает...

Есть идеи?


person marco alves    schedule 07.01.2015    source источник
comment
@matt Я не понимаю круговой аргумент о том, что ответ не является ответом. Я ожидал большей строгости от кого-то с таким количеством очков...   -  person marco alves    schedule 28.06.2015


Ответы (1)


Swift готов выводить типы, но он может справиться только с такой большой двусмысленностью, прежде чем сдастся.

В случае с map(1...100) { arc4random() } слишком много неопределенности в отношении типов. В частности, целочисленные литералы 1 и 100. Это могут быть Int, Int8, UInt32... Иногда Swift по умолчанию использует Int, но если в утверждении больше двусмысленности, он может выйти из равновесия и отказаться.

В этом случае в том же операторе он пытается выяснить, что такое тип { arc4random() }. Он должен иметь возможность сделать вывод, что возвращаемый тип — UInt32, потому что это то, что возвращает arc4random. Но какой тип ввода? Вы не используете его в выражении, так что это не имеет значения, но Swift должен что-то сделать, и он не знает что.

Причина, по которой запись { $0 - $0 + arc4random() } исправляет это, заключается в том, что это помогает определить тип $0 — это должен быть UInt32, потому что это единственное, что вы можете добавить к выводу arc4random. Так что тип закрытия UInt32 -> UInt32. Это означает, что тип 1 и 100 также должен быть UInt32. Это означает, что 1...10 должно быть Range

Наконец, причина, по которой вы получаете жалобу на то, что ClosedInterval не соответствует SequenceType, заключается в том, что существует два возможных типа возврата для оператора ...Range и ClosedInterval. Вы хотите Range, но Swift этого не знает — он не может заставить Range или ClosedInterval работать. Ошибки компилятора Swift имеют тенденцию перечислять один из многих возможных вариантов, которые не будут работать, обычно не тот, который вы пытались использовать, что может немного сбивать с толку.

Лучший способ исправить это, не прибегая к трюку $0 - $0, вероятно, выглядит примерно так:

let a  = map(1...100) { _ in arc4random() }

_ указывает, что вы не заботитесь о вводе в замыкание. Предоставления входного аргумента (даже анонимного) кажется достаточно, чтобы позволить Swift немного расслабиться и по умолчанию использовать Int для двух целочисленных литералов.

person Airspeed Velocity    schedule 07.01.2015