Вы правы в том, что неправильно поняли дженерики. Во-первых, давайте посмотрим на этот протокол:
protocol CommandProtocol {
func execute<T>() -> T
func unExecute<T>() -> T
}
Это говорит "независимо от того, какой тип запрашивает вызывающая сторона, эта функция будет возвращать этот тип". Это невозможно успешно реализовать (под «успешно» я имею в виду «правильно возвращает значение во всех случаях без сбоев»). Согласно этому протоколу, мне разрешено писать следующий код:
func run(command: CommandProtocol) -> MyCustomType {
let result: MyCustomType = command.execute()
return result
}
Нет способа написать execute
, который действительно это сделает, независимо от того, что MyCustomType
.
Ваша путаница усугубляется тонкой синтаксической ошибкой:
func execute<String>() -> String {
Это не означает "T = String", что, как я думаю, вы ожидаете, что это будет означать. Он создает переменную типа String
(которая не имеет ничего общего с строковым типом Swift) и обещает ее вернуть. когда вы позже напишите as! String
, это означает, что «если эти значения не совместимы с запрошенным типом (не« строка », а то, что было запрошено вызывающей стороной), то cra sh.
инструмент, который ведет себя ближе к тому, что вы хотите, это связанный тип. Вы хотели написать это:
protocol CommandProtocol {
associatedType T
func execute() -> T
func unExecute() -> T
}
Но это почти наверняка не будет делать то, что вы хотите. Например, с этим невозможно есть массив команд.
Вместо этого вам, вероятно, нужна структура:
struct Command {
let execute: () -> Void
let undo: () -> Void
}
Затем вы создаете команды, передавая замыкания, которые делают то, что вы хотите:
let command = Command(execute: { self.value += 1 },
undo: { self.value -= 1 })
Альтернативно, поскольку это калькулятор, вы можете сделать это следующим образом:
struct Command {
let execute: (Double) -> Double
let undo: (Double) -> Double
}
let command = Command(execute: { $0 + 1 }, undo: { $0 - 1 })
Тогда ваш абонент будет выглядеть так:
value = command.execute(value)
value = command.undo(value)