구조체 배열의 요소에 대한 참조를 만들 수 있습니까?

Aug 19 2020

주어 Arraystruct

    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. 그러나 그렇게하기 전에 다른 대안을 탐색하고 싶습니다.

답변

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유형 에서 mutating 함수를 사용하고 다음과 같이 변경 사항을 클로저로 전달 하면 더 좋습니다 .

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 = ""
}

그러면 위와 같이 사용할 수 있습니다.

DávidPásztor Aug 19 2020 at 11:16

Arrayis a structstructs는 값 유형 이므로 이는 예상되는 동작 입니다.

당신이 당신을 변환해야합니다, 그래서 당신이 필요한 것은, 참조 형 동작입니다 structA를 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")