我想使用策略模式来注册一组实现协议的对象。当我设置它时,当试图设置作为协议一部分的委托时,出现编译错误。设置委托生成编译错误
出于讨论的目的,我从Swift电子书的代表团章节稍微修改了DiceGame。意义的变化是:
- 协议DiceGame - 声明一个代表
- 类SnakesAndLadders实现DiceGame(以及因此协议和委托)
- 类游戏保持SnakesAndLadders的3个实例为 1)的具体类SnakesAndLadders的 2)“让”恒定协议的DiceGame 3)协议的“VAR”可变DiceGame
我们可以设置代表细如果我们使用具体类(snakesAndLadders)。然而,如果我们使用'let'作为协议(diceGameAsLet),但是它会编译,如果我们将该变量保存为'var'(diceGameAsVar),则会出现编译错误。
这很容易解决,但是,委托本身从不改变,所以应该保持为'let'常量,因为它只是内部属性的变化。对于协议以及它们如何工作和应该如何使用,我一定不能理解某些东西(可能很微妙但很重要)。
class Dice
{
func roll() -> Int
{
return 7 // always win :)
}
}
protocol DiceGame
{
// all DiceGames must work with a DiceGameDelegate
var delegate:DiceGameDelegate? {get set}
var dice: Dice {get}
func play()
}
protocol DiceGameDelegate
{
func gameDidStart(game:DiceGame)
func gameDidEnd(game:DiceGame)
}
class SnakesAndLadders:DiceGame
{
var delegate:DiceGameDelegate?
let dice = Dice()
func play()
{
delegate?.gameDidStart(self)
playGame()
delegate?.gameDidEnd(self)
}
private func playGame()
{
print("Playing the game here...")
}
}
class Games : DiceGameDelegate
{
let snakesAndLadders = SnakesAndLadders()
// hold the protocol, not the class
let diceGameAsLet:DiceGame = SnakesAndLadders()
var diceGameAsVar:DiceGame = SnakesAndLadders()
func setupDelegateAsClass()
{
// can assign the delegate if using the class
snakesAndLadders.delegate = self
}
func setupDelegateAsVar()
{
// if we use 'var' we can assign the delegate
diceGameAsVar.delegate = self
}
func setupDelegateAsLet()
{
// DOES NOT COMPILE - Why?
//
// We are not changing the dice game so want to use 'let', but it won't compile
// we are changing the delegate, which is declared as 'var' inside the protocol
diceGameAsLet.delegate = self
}
// MARK: - DiceGameDelegate
func gameDidStart(game:DiceGame)
{
print("Game Started")
}
func gameDidEnd(game:DiceGame)
{
print("Game Ended")
}
}
哇 - 很好的答案。谢谢。你确切地指出了我错过的那个微妙但重要的东西。协议'DiceGame'可能是一个结构,不能修改,所以编译器是正确的阻止我。我的意图是这个协议只能通过类实现,告诉编译器这个问题消失了,我现在可以干净地使用'let'变量,并且仍然修改委托属性。 (协议DiceGame:类{...}) –