Search code examples
swiftprotocolsinstantiation

In swift, why can't I instantiate a protocol when it has an initialiser?


I understand that generally I cannot instantiate a protocol. But if I include an initialiser in the protocol then surely the compiler knows that when the protocol is used by a struct or class later, it will have an init which it can use? My code is as below and line:

protocol Solution {
  var answer: String { get }
}

protocol Problem {
  var pose: String { get }
}

protocol SolvableProblem: Problem {
  func solve() -> Solution?
}

protocol ProblemGenerator {
  func next() -> SolvableProblem
}

protocol Puzzle {
  var problem: Problem { get }
  var solution: Solution { get }

  init(problem: Problem, solution: Solution)
}

protocol PuzzleGenerator {
  func next() -> Puzzle
}

protocol FindBySolvePuzzleGenerator: PuzzleGenerator {
  var problemGenerator: ProblemGenerator { get }
}

extension FindBySolvePuzzleGenerator {
  func next() -> Puzzle {
    while true {
      let problem = problemGenerator.next()
      if let solution = problem.solve() {
        return Puzzle(problem: problem, solution: solution)
      }
    }
  }
}

The line:

return Puzzle(problem: problem, solution: solution)

gives error: Protocol type 'Puzzle' cannot be instantiated


Solution

  • Imagine protocols are adjectives. Movable says you can move it, Red says it has color = "red"... but they don't say what it is. You need a noun. A Red, Movable Car. You can instantiate a Car, even when low on details. You cannot instantiate a Red.