type - ¿Es posible agregar restricciones de tipo a una extensión de conformidad del protocolo Swift?
tuple swift (2)
EDITAR: Como se señaló en la pregunta actualizada, esto ahora es posible desde Swift 4.1
Actualmente esto no es posible en Swift (a partir de Xcode 7.1). Como indica el error, no puede restringir la conformidad del protocolo ("cláusula de herencia") a una extensión de tipo restringido. Tal vez algún día. No creo que haya una razón profunda para que esto sea imposible, pero actualmente no está implementado.
Lo más cercano que puede obtener es crear un tipo de envoltorio como:
struct FriendlyArray<Element: Friendly>: Friendly {
let array: [Element]
init(_ array: [Element]) {
self.array = array
}
func sayHi() {
for elem in array {
elem.sayHi()
}
}
}
let friendly: Friendly = FriendlyArray(["Foo", "Bar"])
(Es probable que desee extender
FriendlyArray
para que sea un
CollectionType
).
Para una historia de mi propio descenso a la locura de tratar de hacer que esto funcione, y mi rastreo desde el borde, vea NSData, My Old Friend .
Me gustaría extender
Array
para agregar conformidad a un nuevo protocolo, pero solo para matrices cuyos elementos se ajustan a un protocolo específico.
En términos más generales, me gustaría que los tipos (ya sean protocolos o tipos concretos) con parámetros de tipo implementen un protocolo solo cuando los parámetros de tipo coincidan con ciertas restricciones.
A partir de Swift 2.0, esto parece ser imposible. ¿Hay alguna forma en que me estoy perdiendo?
Ejemplo
Supongamos que tenemos el protocolo
Friendly
:
protocol Friendly {
func sayHi()
}
Podemos ampliar los tipos existentes para implementarlo:
extension String: Friendly {
func sayHi() {
print("Greetings from /(self)!")
}
}
"Sally".sayHi()
También podemos extender
Array
para implementar
sayHi()
cuando todos sus elementos son
Friendly
:
extension Array where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}
["Sally", "Fred"].sayHi()
En este punto, el tipo
[Friendly]
debería implementar
Friendly
, ya que cumple con los requisitos del protocolo.
Sin embargo, este código no compila
:
extension Array: Friendly where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}
El mensaje de error es "la extensión del tipo ''Array'' con restricciones no puede tener una cláusula de herencia", que parece cerrar definitivamente la puerta a ese enfoque directo.
¿Hay una solución indirecta?
¿Algún truco inteligente que pueda usar?
¿Quizás haya una forma que implique extender
SequenceType
lugar de
Array
?
Una solución de trabajo haría que este código compilara:
let friendly: Friendly = ["Foo", "Bar"]
Actualización: ¡ Esto ha aterrizado en Swift 4.1, y es algo hermoso!
La
extension Array: Friendly where Element: Friendly
example ahora se compila como se indica en la pregunta original.
La buena noticia es que lo que está pidiendo
Conditional Conformance
está llegando en Swift 4.1: