Array dengan panjang tetap belum didukung. Apa sebenarnya artinya itu? Bukan berarti Anda tidak dapat membuat larik berisi n
banyak hal - jelas Anda bisa melakukannya let a = [ 1, 2, 3 ]
untuk mendapatkan larik tiga Int
detik. Ini berarti bahwa ukuran array bukanlah sesuatu yang dapat Anda deklarasikan sebagai informasi tipe .
Jika Anda menginginkan larik nil
s, pertama-tama Anda memerlukan larik berjenis opsional - [SKSpriteNode?]
, bukan [SKSpriteNode]
- jika Anda mendeklarasikan variabel berjenis non-opsional, apakah itu larik atau nilai tunggal, tidak boleh nil
. (Perhatikan juga bahwa [SKSpriteNode?]
berbeda dari [SKSpriteNode]?
... Anda menginginkan larik opsional, bukan larik opsional.)
Swift sangat eksplisit dengan desain tentang mewajibkan variabel tersebut diinisialisasi, karena asumsi tentang konten referensi yang tidak diinisialisasi adalah salah satu cara program dalam C (dan beberapa bahasa lain) dapat menjadi buggy. Jadi, Anda perlu secara eksplisit meminta [SKSpriteNode?]
array yang berisi 64 nil
s:
var sprites = [SKSpriteNode?](repeating: nil, count: 64)
Ini sebenarnya mengembalikan a [SKSpriteNode?]?
, meskipun: array opsional sprite opsional. (Agak aneh, karena init(count:,repeatedValue:)
seharusnya tidak dapat mengembalikan nol.) Untuk bekerja dengan array, Anda harus membukanya. Ada beberapa cara untuk melakukan itu, tetapi dalam kasus ini saya lebih menyukai sintaks pengikatan opsional:
if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
sprites[0] = pawnSprite
}
sprites
di editor / taman bermain Anda untuk melihat jenis kesimpulannya - sebenarnyaSKSpriteNode?[]?
: array opsional sprite opsional. Anda tidak dapat berlangganan opsional, jadi Anda harus membukanya ... lihat jawaban yang diedit.Hal terbaik yang dapat Anda lakukan untuk saat ini adalah membuat array dengan jumlah awal yang berulang nihil:
Anda kemudian dapat mengisi nilai apa pun yang Anda inginkan.
Di Swift 3.0 :
sumber
Pertanyaan ini telah dijawab, tetapi untuk beberapa informasi tambahan pada saat Swift 4:
Dalam hal kinerja, Anda harus mencadangkan memori untuk larik, jika membuatnya secara dinamis, seperti menambahkan elemen dengan
Array.append()
.Jika Anda mengetahui jumlah minimum elemen yang akan Anda tambahkan, tetapi bukan jumlah maksimumnya, Anda sebaiknya menggunakan
array.reserveCapacity(minimumCapacity: 64)
.sumber
Deklarasikan SKSpriteNode kosong, sehingga tidak perlu dibuka
sumber
Untuk saat ini, yang terdekat secara semantik adalah tupel dengan jumlah elemen tetap.
Tetapi ini (1) sangat tidak nyaman digunakan dan (2) tata letak memori tidak ditentukan. (setidaknya tidak saya ketahui)
sumber
Cepat 4
Anda bisa membayangkannya sebagai larik objek vs. larik referensi.
[SKSpriteNode]
harus berisi objek yang sebenarnya[SKSpriteNode?]
dapat berisi referensi ke objek, ataunil
Contoh
Membuat array dengan 64 default
SKSpriteNode
:Membuat array dengan 64 slot kosong (alias opsional ):
Mengonversi larik opsional menjadi larik objek (diciutkan
[SKSpriteNode?]
menjadi[SKSpriteNode]
):The
count
dari yang dihasilkan tersebutflatSprites
tergantung pada hitungan objek dalamoptionalSprites
: optionals kosong akan diabaikan, yaitu dilewati.sumber
flatMap
sudah tidak digunakan lagi, harus diperbarui menjadicompactMap
jika memungkinkan. (Saya tidak dapat mengedit jawaban ini)Jika yang Anda inginkan adalah larik ukuran tetap, dan menginisialisasinya dengan
nil
nilai, Anda dapat menggunakanUnsafeMutableBufferPointer
, mengalokasikan memori untuk 64 node dengannya, dan kemudian membaca / menulis dari / ke memori dengan memasukkan contoh tipe penunjuk. Ini juga memiliki keuntungan menghindari pemeriksaan apakah memori harus dialokasikan kembali, danArray
memang demikian. Namun saya akan terkejut jika kompiler tidak mengoptimalkannya untuk array yang tidak memiliki panggilan lagi ke metode yang mungkin memerlukan pengubahan ukuran, selain di situs pembuatan.Namun ini tidak terlalu ramah pengguna. Jadi, ayo buat pembungkusnya!
Sekarang, ini adalah kelas, dan bukan struktur, jadi ada beberapa referensi penghitungan overhead yang terjadi di sini. Anda dapat mengubahnya menjadi a
struct
, tetapi karena Swift tidak memberi Anda kemampuan untuk menggunakan penginisialisasi salinan dandeinit
pada struktur, Anda memerlukan metode deallocation (func release() { memory.deallocate() }
), dan semua contoh struktur yang disalin akan mereferensikan memori yang sama.Sekarang, kelas ini mungkin sudah cukup bagus. Penggunaannya sederhana:
Untuk protokol lainnya untuk mengimplementasikan kesesuaian, lihat dokumentasi Array (gulir ke Hubungan ).
sumber
Satu hal yang dapat Anda lakukan adalah membuat kamus. Mungkin sedikit ceroboh mengingat Anda mencari 64 elemen tetapi itu menyelesaikan pekerjaan. Saya tidak yakin apakah ini adalah "cara yang disukai" untuk melakukannya tetapi bekerja untuk saya menggunakan array struct.
sumber
tasks[65] = foo
dalam kedua kasus ini dan kasus array dari pertanyaan.