構造体の配列の要素への参照を作成することは可能ですか?
Aug 19 2020
与えられたArray
とstruct
import Foundation
struct Card {
var flag: String = ""
}
var cards = Array<Card>()
cards.append(Card())
次の操作では、元の配列要素は変更されません
// A copy is created.
var cardCopy = cards[0]
// Will NOT modify cards[0]
cardCopy.flag = "modify0"
print(cards[0].flag)
次の操作は、元の配列要素を変更します
// We can modify cards[0] by
cards[0].flag = "modify"
print(cards[0].flag)
ただし、その意味では効率的ではなく、毎回インデックスアクセスを実行する必要があります。想像してみてください
cards[0].flag0 = "modify"
cards[0].flag1 = "modify"
cards[0].flag2 = "modify"
cards[0].flag3 = "modify"
...
構造体の配列の要素への参照を作成する方法はありますか?私たちが書くことができるように
// How to create a reference to cards[0]?
var cardReference = ...
cardReference.flag0 = "modify"
cardReference.flag1 = "modify"
cardReference.flag2 = "modify"
cardReference.flag3 = "modify"
...
可能性の1つは、に置き換えるstruct
ことclass
です。しかし、そうする前に、他の選択肢を模索したいと思います。
回答
7 gcharita Aug 19 2020 at 11:25
関数を使用して変更を加え、次のCard
ように参照によって構造体を渡すことで、これを実現できます。
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])
または、Card
タイプでミューティング関数を使用し、クロージャとして次のように変更を渡すことで、さらに良い結果が得られます。
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"
}
更新:2番目のアプローチをさらに再利用可能にするために、次のようなプロトコルを定義できます。
protocol Updatable {
mutating func update(block: (inout Self) -> Void)
}
extension Updatable {
mutating func update(block: (inout Self) -> Void) {
block(&self)
}
}
そして作るCard
構造体がそれに準拠:
struct Card: Updatable {
var flag0: String = ""
var flag1: String = ""
var flag2: String = ""
var flag3: String = ""
}
その後、上記のように使用できます。
DávidPásztor Aug 19 2020 at 11:16
Array
is astruct
とstruct
sは値型であるため、これは予想される動作です。
あなたを変換する必要がありますので、何が必要、参照型の動作ですstruct
しclass
。
値型のいくつかのプロパティを一度に変更するための別の解決策は、それを行うmutating
関数を作成し、それを配列要素で呼び出すことです。
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")