是否有可能创建对结构数组元素的引用? [英] Is it ever possible to create a reference to element of array of struct?

查看:29
本文介绍了是否有可能创建对结构数组元素的引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个带有 struct

    import Foundation
    
    struct Card {
        var flag: String = ""
    }
    
    var cards = Array<Card>()
    cards.append(Card())

以下操作不会修改原数组元素

The following operation will NOT modify original array element

    // A copy is created.
    var cardCopy = cards[0]
    
    // Will NOT modify cards[0] 
    cardCopy.flag = "modify0"
    
    print(cards[0].flag)

以下操作将修改原数组元素

The following operation will modify original array element

    // We can modify cards[0] by
    cards[0].flag = "modify"

    print(cards[0].flag)

然而,它在某种意义上并不高效,我们每次都需要执行索引访问.想象一下

However, it isn't efficient in the sense, we need to perform indexing access each time. Imagine

    cards[0].flag0 = "modify"
    cards[0].flag1 = "modify"
    cards[0].flag2 = "modify"
    cards[0].flag3 = "modify"
    ...

有没有办法,我们可以创建对struct数组元素的引用?这样我们就可以写

// How to create a reference to cards[0]?
var cardReference = ...

    cardReference.flag0 = "modify"
    cardReference.flag1 = "modify"
    cardReference.flag2 = "modify"
    cardReference.flag3 = "modify"
    ...

一种可能性是将 struct 替换为 class.但是,在此之前,我想探索其他替代方案.

One of the possibilities is to replace struct with class. But, I would like to explore other alternative, before doing so.

推荐答案

您可以使用函数进行更改并通过引用传递 Card 结构,如下所示:

You can achieve that using a function to make your changes and pass the Card struct by reference like this:

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 函数并作为闭包传递您的更改来获得更好的效果:

or even better by using a mutating function in Card type and pass as a closure your changes like that:

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

更新:为了使第二种方法更具可重用性,您可以定义如下协议:

Update: To make the second approach even more reusable, you can define a protocol like this:

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

然后你就可以像上面一样使用它了.

Then you can use it just like above.

这篇关于是否有可能创建对结构数组元素的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆