/ / Tipo de retorno para todas las implementaciones de un protocolo: rápidos, protocolos

Tipo de retorno para todas las implementaciones de un protocolo: rápidos, protocolos

Tengo un pequeño problema. Necesito especificar un valor de retorno para una función que pueda devolver cada implementación de un Protocolo. Por ejemplo:

Mi protocolo

protocol MyProtocol {
//some functions
}

Implementaciones:

class ClassA: MyProtocol {
}

class ClassB: MyProtocol {
}

La función "problema":

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

//EDITAR: Aquí es donde necesito el resultado

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

Uso:

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

El problema es ese result no es realmente ClassA.Type, lo que debería ser, es ahora MyProtocol.Type y no puedo pasar esto a la siguiente función. Cuando doy result el valor específico de ClassA.self Todo funciona. No puedo enviarlo a as! ClassA.self porque no se si tiene que ser ClassA o ClassB o Class9000

Entonces la pregunta es. ¿Existe otro tipo de retorno como MyProtocol.Type para la función getClassByString() o una forma completamente diferente de obtener ClassA.Type a result ?

Respuestas

1 para la respuesta № 1

Creo que su problema aquí no es exactamente como lo describe: el result de su ejemplo en realidad parece ser un ClassA.Type en Playground, pero el problema que sospecho es qué haces con él a continuación. Tu protocolo no dice cómo tales tipos deben instanciarse de manera genérica, por lo que el tipo devuelto no puede ser instanciado.

Hice algunos cambios en tu ejemplo y ahora funciona ...

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