/ / Тип повернення для всіх реалізацій протоколу - swift, протоколи

Тип повернення для всіх реалізацій протоколу - swift, протоколи

У мене є невелика проблема. Мені потрібно вказати повернене значення для функції, яка може повертати кожну реалізацію протоколу. Наприклад:

Мій протокол:

protocol MyProtocol {
//some functions
}

Виконання:

class ClassA: MyProtocol {
}

class ClassB: MyProtocol {
}

Функція "проблема":

func getClassByString(_ name: String) -> MyProtocol.Type {
switch name {
case "a":
return ClassA.self
case "b":
return ClassB.self
default:
return ClassC.self
}
}

// EDIT: Тут мені потрібен результат

final class Mapper<N: MyProtocol> {
public func map() -> N?{
if let klass = N.self as? MyProtocol.Type {
return klass as? N
}
return nil
}
}

Використання:

let className = "a" //this String comes from a JSON
let result = getClassByString(className)

let mappingResult = Mapper<result>().map() //undeclared identifier "result" error
let mappingResult = Mapper<ClassA>().map() //works but i do not know if it is ClassA

Проблема в тому result не справді ClassA.Type, що має бути, це зараз MyProtocol.Type і я не можу передати це наступній функції. Коли даю result питоме значення ClassA.self все працює. Я не можу це зробити as! ClassA.self тому що я не знаю, чи має це бути ClassA або ClassB або Class9000

Тож питання. Чи існує інший тип повернення типу MyProtocol.Type для функції getClassByString() або зовсім інший спосіб отримати ClassA.Type до result ?

Відповіді:

1 для відповіді № 1

Я думаю, що ваша проблема тут не зовсім така, як ви описуєте - result Вашого прикладу насправді здається ClassA.Type на дитячому майданчику, але проблема, на яку я підозрюю, полягає в тому, що ви з ним будете робити далі. У вашому протоколі не сказано як такі типи мають бути створені загальним чином, тому повернутий тип не може Бути екземпляр.

Я зробив кілька змін у вашому прикладі, і зараз він працює ...

protocol MyProtocol {
//some functions
init() // To instantiate generically, there MUST be an accepted pattern for init()
}

class ClassA: MyProtocol {
required init() {}
}
class ClassB: MyProtocol {
required init() {}
}
class ClassC: MyProtocol {
required init() {}
}

func getClassByString(_ name: String) -> MyProtocol.Type {
switch name {
case "a":
return ClassA.self
case "b":
return ClassB.self
default:
return ClassC.self
}
}

let className = "a" //this String comes from a JSON
let result = getClassByString(className) // ClassA.Type
let a = result.init() // ClassA