Saya ingin meneruskan Swift saya Array
account.chats
ke sebagai chatsViewController.chats
referensi (sehingga ketika saya menambahkan obrolan ke account.chats
, chatsViewController.chats
tetap menunjuk ke account.chats
). Yaitu, saya tidak ingin Swift memisahkan dua larik ketika panjangnya account.chats
berubah.
arrays
swift
pass-by-reference
ma11hew28
sumber
sumber
account
variabel global dan mendefinisikanchats
milikChatsViewController
sebagai:var chats: [Chat] { return account.chats }
.Jawaban:
Struktur di Swift diteruskan oleh nilai, tetapi Anda dapat menggunakan
inout
pengubah untuk mengubah larik Anda (lihat jawaban di bawah). Kelas dilewatkan dengan referensi.Array
danDictionary
di Swift diimplementasikan sebagai struct.sumber
NSArray
karenaNSArray
dan array Swift memiliki perbedaan semantik yang halus (seperti tipe referensi), dan itu mungkin membawa Anda ke lebih banyak bug.inout
dengan Structs?Untuk operator parameter fungsi kita menggunakan:
let (itu operator default, jadi kita bisa menghilangkan let ) untuk membuat parameter konstan (itu berarti kita tidak bisa memodifikasi bahkan salinan lokal);
var untuk membuatnya menjadi variabel (kita dapat memodifikasinya secara lokal, tetapi tidak akan mempengaruhi variabel eksternal yang telah diteruskan ke fungsi); dan
inout untuk menjadikannya sebuah parameter inout. In-out berarti meneruskan variabel dengan referensi, bukan dengan nilai. Dan itu membutuhkan tidak hanya untuk menerima nilai dengan referensi, dengan juga untuk meneruskannya dengan referensi, jadi teruskan dengan & -
foo(&myVar)
bukan hanyafoo(myVar)
Jadi lakukan seperti ini:
Tepatnya, ini bukan hanya referensi, tetapi alias nyata untuk variabel eksternal, jadi Anda dapat melakukan trik seperti itu dengan tipe variabel apa pun, misalnya dengan integer (Anda dapat menetapkan nilai baru untuk itu), meskipun itu mungkin bukan praktik yang baik dan mungkin akan membingungkan untuk mengubah tipe data primitif seperti ini.
sumber
inout
posisinya telah berubah, yaitufunc addItem(localArr: inout [Int])
var
tidak lagi tersedia untuk atribut parameter fungsi.Definisikan diri Anda sebagai
BoxedArray<T>
yang mengimplementasikanArray
antarmuka tetapi mendelegasikan semua fungsi ke properti tersimpan. Dengan demikianGunakan di
BoxedArray
mana pun Anda akan menggunakan fileArray
. PenetapanBoxedArray
akan menjadi dengan referensi, itu adalah kelas, dan dengan demikian perubahan pada properti yang disimpan, melaluiArray
antarmuka, akan terlihat oleh semua referensi.sumber
String
merupakan subtipe dariAny
TAPI jika Andaimport Foundation
kemudianString
menjadi subtipe dariAnyObject
.Untuk Swift versi 3-4 (XCode 8-9), gunakan
sumber
Sesuatu seperti
???
sumber
func test(b: inout [Int])
... mungkin ini adalah sintaks lama; Saya baru masuk ke Swift pada 2016 dan jawaban ini dari 2014 jadi mungkin dulu semuanya berbeda?Satu opsi lainnya adalah meminta konsumen dari array meminta pemiliknya sesuai kebutuhan. Misalnya, sesuatu di sepanjang baris:
Anda kemudian dapat memodifikasi array sebanyak yang Anda suka di dalam kelas Akun. Perhatikan bahwa ini tidak membantu Anda jika Anda juga ingin mengubah larik dari kelas pengontrol tampilan.
sumber
Menggunakan
inout
adalah salah satu solusi tetapi tidak terasa cepat bagi saya karena array adalah tipe nilai. Secara gaya, saya pribadi lebih suka mengembalikan salinan yang dimutasi:sumber
inout
secara universal lebih baik karena menghemat baterai. Yang menurut saya keterbacaan, keabadian, dan keamanan utas dari solusi ini secara universal lebih baik dan inout hanya boleh digunakan sebagai pengoptimalan dalam kasus yang jarang terjadi di mana kasus penggunaan menjaminnya.menggunakan a
NSMutableArray
atau aNSArray
, yang merupakan kelasDengan cara ini Anda tidak perlu menerapkan pembungkus apa pun dan dapat menggunakan build in bridging
sumber