protocol Deck {
var cards: [String] {get set} // {get mutable set}
}
struct MyDeck: Deck {
var cards: [String] = (1...7).map {_ in return String(rand())}
}
只是感兴趣我需要在协议中指定{get mutable set}吗? 如果我的setter改变了我的结构,那么找不到任何关于为什么不在setter声明中使用mutable关键字的文档
答案 0 :(得分:6)
首先请注意,讨论的关键字是 mutating
,而不是mutable
。
set
的默认状态为mutating
mutating
是设置者的默认状态,因此您无需明确使用mutating
关键字来指定此。< / LI>
对于getter和setter,以下默认行为保持
get
默认为nonmutating
set
默认为mutating
因此,指定... { get set }
的协议,例如(如您的示例中)计算属性,期望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 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 ...") }
}
}
最后,有趣的是,如果我们(对于某些协议属性)蓝图将一个setter作为默认值(... {get set}
),即默认为mutating set
,我们仍然可以明确地遵循这样的协议nonmutating
setter
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 */
}
}
我可以假设这是允许的,因为我们让符合协议的结构包含一个比蓝图更具限制性的setter ,关于变异self
。如果我们对mutating
吸气剂进行蓝图,自然也是如此:我们仍然可以使用nonmutating
符合这样的协议。
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 }
}
}