Swift可变设置属性

时间:2016-05-24 20:49:10

标签: swift

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关键字的文档

1 个答案:

答案 0 :(得分:6)

首先请注意,讨论的关键字是 mutating ,而不是mutable

set的默认状态为mutating

  • 要快速回答您的问题:mutating是设置者的默认状态,因此您无需明确使用mutating关键字来指定此。< / LI>

详细信息

对于getter和setter,以下默认行为保持

  • get默认为nonmutating
  • set默认为mutating

因此,指定... { get set }的协议,例如(如您的示例中)计算属性,期望nonmutating get的默认mutating setstruct符合这样的协议

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