如何修复Xcode中的'不能在不可变值上使用变异成员:'自我'是不可变的'错误

时间:2019-01-02 11:43:40

标签: swift

我创建一个随机数并将其分配给变量randomNumber。然后,当我尝试将随机数作为emojis数组的索引附加到空数组arrayOfEmojis时,出现错误:

  

“不能在不可变值上使用变异成员:“自身”是不可变的”

我也从表情符号中得到了错误吗?

import GameKit

struct EmojiProvider {
    var emojis = ["", "", "", "", "", "", "", "", "☺️", "", "", "", "", "", "", ""]
    var arrayOfEmojis: [String]

    func generateEmoji() -> [String] {
        for i in 1...3 {
            var randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: emojis.count)
            arrayOfEmojis.append(emojis[randomNumber]) //error!
        }
        return arrayOfEmojis
    }
}

2 个答案:

答案 0 :(得分:0)

问题在于struct是一个值类型,当您修改其任何实例属性时,实际上是在修改结构实例本身。因此,当您在append上调用arrayOfEmojis时,不仅会突变arrayOfEmojis,而且会突变EmojiProvider实例本身。您可以通过将功能标记为变异来摆脱警告。

mutating func generateEmoji() -> [String] { ...

但是,在我看来,您实际上想做的只是从数组中获取3个随机元素,而您当前的实现方式是每次generateEmoji时从数组中获取3个随机元素。函数会被调用并将其追加到arrayOfEmojis数组中,随着您不断调用generateEmoji函数,数组会越来越大。

要获得该行为,请将您的实现更改为以下内容:

struct EmojiProvider {
    var emojis = ["", "", "", "", "", "", "", "", "☺️", "", "", "", "", "", "", ""]

    func generateEmoji() -> [String] {
        var arrayOfEmojis = [String]()
        for _ in 1...3 {
            let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: emojis.count)
            arrayOfEmojis.append(emojis[randomNumber])
        }
        return arrayOfEmojis
    }
}

或者使用generateEmoji来简化map的实现:

func generateEmoji() -> [String] {
    return (1...3).map{_ ->String in emojis[GKRandomSource.sharedRandom().nextInt(upperBound: emojis.count)]}
}

答案 1 :(得分:0)

之所以发生这种情况,是因为当您拥有struct而不是class时,您是在更改实例本身。
因此,当您尝试突变self时,请将函数标记为mutating

mutating func generateEmoji() -> [String] {

此外,我建议您选择一个随机元素,如下所示:

return (1...3).compactMap { _ in emojis.randomElement() }

...如果您以后不想访问它,请留下整个arrayOfEmojis


完整的代码应为:

struct EmojiProvider {
    var emojis = ["", "", "", "", "", "", "", "", "☺️", "", "", "", "", "", "", ""]

    mutating func generateEmoji() -> [String] {
        return (1...3).compactMap { _ in emojis.randomElement() }
    }
}

您还可以做的是将EmojiProvider设为类,而不是结构。
然后,您可以输入以下代码:

class EmojiProvider {
    var emojis = ["", "", "", "", "", "", "", "", "☺️", "", "", "", "", "", "", ""]

    func generateEmoji() -> [String] {
        return (1...3).compactMap { _ in emojis.randomElement() }
    }
}