Extension de construit de type générique dans Swift
Est-il possible d'étendre une classe générique pour un spécialisé/construit de type générique? Je tiens à exprimer Int Tableaux avec une méthode pour calculer la somme de ses éléments.
par exemple
extension Array<Int> {
func sum() -> Int {
return reduce(0) { $0 + $1 }
}
}
Vous devez vous connecter pour publier un commentaire.
Cela peut être réalisé en utilisant des extensions de protocole (Voir Le Langage De Programmation Swift: Protocoles pour plus d'informations). Dans Swift 3:
À la somme juste
Int
s que vous pouvez faire:Utilisation:
Ou, pour quelque chose de plus générique vous pourrait ce @Wes Campaigne suggéré de créer un
Addable
protocole:Ensuite, étendre
Sequence
pour ajouter des séquences deAddable
éléments:Utilisation:
sum
lecture seule propriété calculée au lieu d'un zéro-paramètre de la fonction.==
) peut être appliquée qu'à des extensions à un protocole, pas struct ou class.IntegerType
? Je pense que votre réponse serait beaucoup plus générique. Peut-être le faire de cette façon de faire s'étendant deuxdouble
&Int
inutile, mais ensuite, vous devez créer une autre pour lesString
Réussi à obtenir quelque chose de travail dans un extensible, générique de la mode sans pour autant abuser du système de type trop mal, il a cependant certaines limites.
Plus précisément: avec cette solution, le type d'inférence ne fonctionne pas sur le paramètre
sum()
méthode, vous devez donc soit annoter le rendement attendu de type ou de lui donner une valeur de départ (à partir de laquelle on peut déduire le type).Note également que cette fonction retourne une valeur de type Facultatif: si pour une raison quelconque, une somme du type attendu ne peut pas être calculée à partir de la matrice, il retourne nil.
Pour illustrer:
func +
dans le protocole n'est pas mis en œuvre par toute la mise en œuvre de classes?extension Array where Element: Addable
est le chemin à parcourir.Semble que vous ne pouvez pas. Le plus proche que nous pouvons obtenir est la fonction
Swift va vous permettre d'ajouter une extension sur le Tableau de la classe, mais pas spécifiquement à une version spécialisée de la classe.
error: <REPL>:108:1: error: non-nominal type 'Array<Int>' cannot be extended
Vous pouvez étendre la classe Array.
Le problème est maintenant avec le
+
opérateurC'est un peu normal puisque nous ne pouvons pas être sûr que le
+
opérateur sera surchargé pour tous les types possibles qui pourraient être utilisés dans un tableau.Pour essayer de contrainte de l'opération que sur certaines classes. Quelque chose comme
Conceptuellement, cela devrait fonctionner (actuellement, il semble qu'il y a un bug, Xcode se bloque lors de l'évaluation d'une aire de jeux à l'aide de ce code). Dans la suite qu'il fonctionne, nous ne pouvons pas utiliser cette astuce depuis le type
Int
n'est pas une classe.J'ai également regardé l'extension de la classe Array avec un protocole mais encore une fois
Int
pas être une classe rend impossible. Si les types numériques ont été les classes, ce serait bien si nous pouvions avoir un protocole à définir qu'une classe peut être ajoutée tout commeComparable
ouEquatable
mais ma compréhension est que le protocole ne permet pas de définir la fonction générique qui est nécessaire pour créer unAddable
protocole.Edit:
Comme indiqué par d'autres réponses, vous pouvez le faire fonctionner pour Int explicitement à la vérification et à la conversion en Int la fermeture. Je suppose que j'ai raté ça va enquêter. Mais il serait bien si on pouvait avoir un générique façon de travailler avec les types numériques.
Alexander,
Voici comment vous pouvez le faire:
Fonctionne comme un charme, testé dans la cour de récréation. Cependant, vous pourriez avoir des ennuis si vous appelez cette fonction sur les différents types de tableaux.
Il est possible de retourner une véritable somme de la valeur après avoir testé par l'int type de
sum()
. Ce faisant, je permettrait de résoudre le problème comme suit:vous pouvez le faire aussi bien