used type tuple only has generic functions constraint because associated swift generics

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.