เป็นไปได้ไหมที่จะสร้างการอ้างอิงถึงองค์ประกอบของอาร์เรย์ของโครงสร้าง
ให้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"
...
หนึ่งในความเป็นไปได้คือการแทนที่ด้วยstruct
class
แต่ฉันต้องการสำรวจทางเลือกอื่นก่อนที่จะทำเช่นนั้น
คำตอบ
คุณสามารถทำได้โดยใช้ฟังก์ชันเพื่อทำการเปลี่ยนแปลงของคุณและส่งผ่านโครงสร้าง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"
}
อัปเดต : เพื่อให้แนวทางที่สองสามารถนำกลับมาใช้ใหม่ได้มากขึ้นคุณสามารถกำหนดโปรโตคอลดังนี้:
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 = ""
}
จากนั้นคุณสามารถใช้งานได้เหมือนด้านบน
นี่คือลักษณะการทำงานที่คาดไว้เนื่องจากArray
เป็น a struct
และ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")