functions - swift generics
¿Por qué este protocolo "solo se puede usar como una restricción genérica"? (2)
Es posible implementar esto invirtiendo el control: en lugar de devolver un valor de someFunc , pasamos a un consumidor que puede aceptar cualquier tipo de implementación de ProtocolWithAlias y hacer algo con él.
protocol ProtocolWithAlias {
typealias T
}
protocol ProtocolConsumer {
func consume<T: ProtocolWithAlias>(value: T)
}
protocol AnotherProtocol {
func someFunc(consumer: ProtocolConsumer)
}
Este truco se conoce como la transformación de la función al estilo de paso de continuación (CPS) . Desafortunadamente, no pude encontrar ninguna manera de implementar esto sin CPSing. La característica del sistema de tipos que estamos buscando es de tipos existenciales (y this hilo tiene una buena explicación), pero creo que Swift no los admite (todavía).
¿Por qué la otra respuesta no es correcta? Lo que dice esta firma:
func someFunc<T:ProtocolWithAlias>() -> T
es que esta función puede devolver un valor de tipo T para cualquier tipo de implementación de ProtocolWithAlias que el llamante elija, pero queríamos que fuera elegido por el destinatario .
Ni siquiera es posible escribir una implementación sensata de esta función. Supongamos que tengo una implementación de someFunc : podría crear una nueva clase implementando ProtocolWithAlias y solicitar a SomeFunc que de alguna manera cree una instancia de esta clase:
class Uninhabited: ProtocolWithAlias {
typealias T = Int
init(nope: Uninhabited) {}
}
...
let impossible: Uninhabited = someFunc<Uninhabited>()
Estoy intentando hacer lo siguiente en Swift:
protocol ProtocolWithAlias {
typealias T
}
protocol AnotherProtocol {
func someFunc() -> ProtocolWithAlias
}
Pero me sale el error: el Protocol ''ProtocolWithAlias'' can only be used as a generic constraint because it has Self or associated type requirements
.
¿Es posible hacer algo como esto? El mensaje de error (o al menos la parte de " only be used as a generic constraint
") no parece tener mucho sentido para mí.
Estoy usando el último Xcode 6 beta 3.
¡Gracias!
Prueba esto:
func someFunc<T:ProtocolWithAlias>() -> T