我创建一个随机数并将其分配给变量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
}
}
答案 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() }
}
}