Как создать массив объектов фиксированного размера
В Swift я пытаюсь создать массив из 64 SKSpriteNode. Я хочу сначала инициализировать его пустым, тогда я бы поставил Sprites в первые 16 ячеек и последние 16 ячеек (имитирующих шахматную игру).
Из того, что я понял в документе, я бы ожидал чего-то вроде:
var sprites = SKSpriteNode()[64];
или
var sprites4 : SKSpriteNode[64];
Но это не сработает.
Во втором случае я получаю сообщение об ошибке: "Массивы фиксированной длины еще не поддерживаются". Это может быть реально? Для меня это звучит как основная особенность.
Мне нужно получить доступ к элементу напрямую по их индексу.
Ответы
Ответ 1
Массивы с фиксированной длиной еще не поддерживаются. Что это значит? Не то чтобы вы не могли создать массив из n
многих вещей - очевидно, вы можете просто сделать let a = [ 1, 2, 3 ]
, чтобы получить массив из трех Int
s. Это означает, что размер массива не является тем, что вы можете объявить как информацию о типе.
Если вам нужен массив из nil
s, вам сначала понадобится массив необязательного типа - [SKSpriteNode?]
, а не [SKSpriteNode]
- если вы объявите переменную не необязательного типа, будь то массив или одно значение, оно не может быть nil
. (Также обратите внимание, что [SKSpriteNode?]
отличается от [SKSpriteNode]?
... вам нужен массив необязательных, а не необязательный массив.)
Swift очень ясен по дизайну, требуя инициализации переменных, поскольку предположения о содержании неинициализированных ссылок являются одним из способов, позволяющих программам на C (и некоторых других языках) стать ошибками. Итак, вам нужно явно запросить массив [SKSpriteNode?]
, содержащий 64 nil
s:
var sprites = [SKSpriteNode?](count:64, repeatedValue: nil)
Это фактически возвращает [SKSpriteNode?]?
, хотя: дополнительный массив дополнительных спрайтов. (Немного странно, так как init(count:,repeatedValue:)
не сможет вернуть нуль.) Чтобы работать с массивом, вам нужно развернуть его. Есть несколько способов сделать это, но в этом случае я бы предпочел необязательный синтаксис привязки:
if var sprites = [SKSpriteNode?](count:64, repeatedValue: nil) {
sprites[0] = pawnSprite
}
Ответ 2
Самое лучшее, что вы сейчас можете сделать, это создать массив с начальным счетчиком, повторяющим нуль:
var sprites = [SKSpriteNode?](count: 64, repeatedValue: nil)
Затем вы можете заполнить любые значения, которые вы хотите.
В Swift 3.0:
var sprites = [SKSpriteNode?](repeating: nil, count: 64)
Ответ 3
Объявить пустой SKSpriteNode, поэтому не нужно будет отказываться
var sprites = [SKSpriteNode](count: 64, repeatedValue: SKSpriteNode())
Ответ 4
В настоящее время семантически ближайшим является кортеж с фиксированным числом элементов.
typealias buffer = (
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode,
SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode)
Но это (1) очень неудобно в использовании и (2) макет памяти undefined. (по крайней мере, неизвестно мне)
Ответ 5
Одна вещь, которую вы могли бы сделать, - создать словарь. Может быть немного неряшливо, учитывая, что вы ищете 64 элемента, но он выполняет свою работу. Я не уверен, что это "предпочтительный способ", но он работал у меня с использованием массива структур.
var tasks = [0:[forTasks](),1:[forTasks](),2:[forTasks](),3:[forTasks](),4:[forTasks](),5:[forTasks](),6:[forTasks]()]