protocol Deck {
var cards: [String] {get set} // {get mutable set}
}
struct MyDeck: Deck {
var cards: [String] = (1...7).map {_ in return String(rand())}
}
只是有兴趣我需要在协议(protocol)中指定 {get mutable set} 吗?
如果我的 setter 改变了我的结构,找不到任何关于为什么不在 setter 声明中使用 mutable 关键字的文档
最佳答案
首先注意讨论的关键字是 mutating
,而不是 mutable
。set
的默认状态是 mutating
mutating
是 setter 的默认状态,因此您无需明确使用 mutating
关键字来指定它。 细节
对于 getter 和 setter,以下默认行为成立
get
是 nonmutating
,默认为 set
是 mutating
,默认为 因此,指定
... { get set }
的协议(protocol),例如(在您的示例中),计算属性,期望符合此类协议(protocol)的 nonmutating get
的默认 mutating set
和 struct
protocol Deck {
var cards: [String] {get set}
}
// implicitly, OK
struct MyDeckA: Deck {
var mutateMe: Int = 0
var cards: [String] {
get { return ["foo"] }
set { mutateMe += 1 }
}
}
// explicitly, OK
struct MyDeckB: Deck {
var mutateMe: Int = 0
var cards: [String] {
nonmutating get { return ["foo"] }
mutating set { mutateMe += 1 }
}
}
/* error, MyDeckC does not conform to Deck
(mutating getter, wheres a nonmutating one is blueprinted!) */
struct MyDeckC: Deck {
var mutateMe: Int = 0
var cards: [String] {
mutating get { return ["foo"] }
mutating set { mutateMe += 1 }
}
}
如果我们想要一个与上述默认情况不同的 getter 或 setter,我们需要指定这一点(在协议(protocol)中以及明确地说符合此类协议(protocol)的结构)。protocol Deck {
var cards: [String] {mutating get nonmutating set}
}
/* when conforming to this non-default get/set setup blueprinted in
protocol Deck, we need to explicitly specify our non-default
(w.r.t. mutating) getter and setter */
struct MyDeckD: Deck {
var mutateMe: Int = 0
var cards: [String] {
mutating get { mutateMe += 1; return ["foo"] }
nonmutating set { print("I can't mutate self ...") }
}
}
最后,有趣的是,如果我们(对于某些协议(protocol)属性)将一个 setter 蓝图作为默认值( ... {get set}
),即默认为 mutating set
,我们仍然可以通过明确的 nonmutating
setter 遵守这样的协议(protocol)protocol Deck {
var cards: [String] {get set}
}
struct MyDeckE: Deck {
var mutateMe: Int = 0
var cards: [String] {
get { return ["foo"] }
nonmutating set { print("I can't mutate self ...") }
/* setter cannot mutate self */
}
}
我可以假设这是允许的,因为我们让符合协议(protocol)的结构包含一个比蓝图更严格的 setter,关于变异 self
。如果我们为 mutating
getter 设计蓝图,自然也是如此:我们仍然可以使用 nonmutating
来遵守这样的协议(protocol)。protocol Deck {
var cards: [String] {mutating get set}
}
struct MyDeckF: Deck {
var mutateMe: Int = 0
var cards: [String] {
nonmutating get { print("I can't mutate self ..."); return ["foo"] }
/* getter cannot mutate self */
set { mutateMe += 1 }
}
}
关于Swift 可变设置在属性中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37423595/