[swift] Le type de n'importe quelle fonction
laurris
Membre
J'ai besoin de grouper des fonctions acceptant différents types d'arguments et retournant également des types différents.
Problème, il n'existe pas de type ou de protocole qui correspond à "une fonction en général".
Certes, on peut définir un type fonction dont les arguments et le return type se conforment à un protocole commun, par exemple AnyObject.
let function:(AnyObject) -> AnyObject
Si j'essaie d'affecter une fonction existante à la variable function, le compiler accepte une fonction de type
(AnyObject) -> NSNumber
, mais pas
(NSNumber) -> AnyObject
En gros, il ne veut bien caster le return type mais pas l'argument.
Pourquoi ? Est-ce une limitation (peut-être provisoire) du type checker ou y a-t'il une raison plus fondamentale à cela. Comment workarounder la chose ?
Xcode 7.2 swift 2.1
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
C'est un peu logique...
Si tu prends ces 2 fonctions :
Elles ont le même nom. Maintenant si le compilo ne s'emmêle pas les pinceaux c'est parce qu'elles n'ont pas la meÌ‚me signature. C'est le type d'argument qui est ici décisif dans le choix de la façon à appeler. Un table est constituée à la compilation et si on change la signature d'une méthode on risque vite de la perdre à jamais.
C'est aussi pour ça que :
Fera une belle erreur :
Le return type n'aide pas non plus cela dit :
Mènera exactement au meÌ‚me message d'erreur.
À la rigueur tu peux utiliser la geÌneÌriciteÌ :
dummy renverra un Double mais juste parce qu'on lui a dit de le faire, sans plus.
Bref je ne sais pas ce que tu essaie de faire mais ça ne semble pas être une bonne idée...
PS: tu ne peux pas deÌclarer un type de fonction générique. Juste deÌclarer des fonctions génériques comme le code plus haut.
n'a aucune chance d'exister.
Merci Pyroh pour ta réponse.
Ce que j'essaie de faire, c'est simplement d'appeler une fonction à partir d'un nom:String de fonction. Je sais, ce n'est pas très typé, pas très swift-like, mais c'est comme ça. La correspondance se fait avec un dictionnaire de type <String,FunctionType> et c'est pour cela que je voudrais que toutes mes fonctions soient de type FunctionType.
Dans ton exemple, tu prends le cas de deux fonctions avec le même nom mais des arguments de type différents. D'accord, je comprends que ce soit ambigu. Mais supposons qu'il n'existe dans le code compilé qu'une seule fonction dont l'argument puisse être upcasté vers un autre type.
Qu'est-ce qui empêche de convertir dummy quand on fait: (ce qui donne une erreur)
Je ne vois pas d'ambiguà¯té là -dedans. NSNumber est bien un sous-type de AnyObject et il n'existe pas d'autre fonction du même nom dont l'argument est un sous-type de AnyObject.
D'autant que le return type peut lui, être upcasté:
Pas d'erreur.
Il existe peut-être d'autres contraintes propres au compiler et que j'ignore, mais je trouve dommage que mon exemple ne marche pas.
J'avais lu un long texte sur l'upcasting et le downcasting de Swift (peut être des release notes) mais plus moyen de mettre la main dessus. Bref ce que tu essaie de faire est impossible.
Sinon si tu veux pouvoir faire appel à une fonction depuis un string utilise simplement KVC en faisant de tes classes des sous classes de NSObject. Tu vas pouvoir utiliser les selectors et performSelector.
C'est pas très swift-friendly cela dit. ApreÌ€s si tu nous dit dans quel contexte tu as besoin de ça on peut (peut-être) t'aider à reÌ-architecturer tout ça.
Le contexte c'est le port de NSExpression en swift sans runtime Objective-C.
Le mieux est de montrer ce que j'ai écrit pour l'instant. La fonction en question se trouve ici: NSExpression(forFunction:arguments:)
Comme on peut le voir en commentaire, les fonctions pré-définies ont 4 ou 5 signatures différentes. Je crois que je vais finir par créer une collection par signature et rechercher dans chaque collection l'une après l'autre à partir du nom de fonction.