我想使用策略模式來註冊一組實現協議的對象。當我設置它時,當試圖設置作爲協議一部分的委託時,出現編譯錯誤。設置委託生成編譯錯誤
出於討論的目的,我從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:類{...}) –