Yapı dizisi elemanına bir başvuru yaratmak mümkün müdür?
Bir göz önüne alındığında Array
ilestruct
import Foundation
struct Card {
var flag: String = ""
}
var cards = Array<Card>()
cards.append(Card())
Aşağıdaki işlem orijinal dizi elemanını DEĞİŞTİRMEZ
// A copy is created.
var cardCopy = cards[0]
// Will NOT modify cards[0]
cardCopy.flag = "modify0"
print(cards[0].flag)
Aşağıdaki işlem orijinal dizi elemanını değiştirecek
// We can modify cards[0] by
cards[0].flag = "modify"
print(cards[0].flag)
Ancak, bu anlamda verimli değil, her seferinde indeksleme erişimi gerçekleştirmemiz gerekiyor. Hayal etmek
cards[0].flag0 = "modify"
cards[0].flag1 = "modify"
cards[0].flag2 = "modify"
cards[0].flag3 = "modify"
...
Yapı dizisi elemanına referans oluşturmanın bir yolu var mı? Böylece yazabiliriz
// How to create a reference to cards[0]?
var cardReference = ...
cardReference.flag0 = "modify"
cardReference.flag1 = "modify"
cardReference.flag2 = "modify"
cardReference.flag3 = "modify"
...
Olasılıklardan biri değiştirmektir struct
ile class
. Ama bunu yapmadan önce başka bir alternatif keşfetmek isterim.
Yanıtlar
Değişikliklerinizi yapmak ve Card
yapıyı aşağıdaki gibi referansla geçmek için bir işlev kullanarak bunu başarabilirsiniz :
func update(card: inout Card) {
card.flag0 = "modify"
card.flag1 = "modify"
card.flag2 = "modify"
card.flag3 = "modify"
}
var cards = Array<Card>()
cards.append(Card())
update(card: &cards[0])
hatta daha da iyisi, Card
tipte bir mutasyon işlevi kullanarak ve değişikliklerinizi şu şekilde tamamlayarak geçebilir:
struct Card {
var flag0: String = ""
var flag1: String = ""
var flag2: String = ""
var flag3: String = ""
mutating func update(block: (inout Card) -> Void) {
block(&self)
}
}
var cards = Array<Card>()
cards.append(Card())
cards[0].update {
$0.flag0 = "modify" $0.flag1 = "modify"
$0.flag2 = "modify" $0.flag3 = "modify"
}
Güncelleme : İkinci yaklaşımı daha da tekrar kullanılabilir hale getirmek için aşağıdaki gibi bir protokol tanımlayabilirsiniz:
protocol Updatable {
mutating func update(block: (inout Self) -> Void)
}
extension Updatable {
mutating func update(block: (inout Self) -> Void) {
block(&self)
}
}
ve Card
yapıyı buna uygun hale getirin:
struct Card: Updatable {
var flag0: String = ""
var flag1: String = ""
var flag2: String = ""
var flag3: String = ""
}
O zaman yukarıdaki gibi kullanabilirsiniz.
Bu beklenen davranıştır, çünkü Array
a struct
ve struct
s değer türleridir.
İstemiyorsun, mutfakta annene dönüştürmek gerekir böylece Ne gerek, başvuru türü davranıştır struct
a class
.
Bir değer türünün çeşitli özelliklerini tek seferde değiştirmek için başka bir çözüm mutating
, bunu yapan bir işlev oluşturmak ve bunu dizi öğesinde çağırmaktır.
struct Card {
var flag: String = ""
var flag2 = ""
mutating func update(flag: String, flag2: String) {
self.flag = flag
self.flag2 = flag2
}
}
var cards = [Card(flag: "a", flag2: "b")]
cards[0].update(flag: "b", flag2: "c")