2014-09-11 2 views
0

Dans d'autres langages de haut niveau, vous pouvez utiliser la correspondance de modèle pour la surcharge de fonctions, par exemple dans Mathematica. Par exemple, vous pouvez écrire du code élégant sans instruction if, voici un exemple de ce que je veux dire:Comment est-ce que je peux surcharger des fonctions avec la correspondance de modèle dans Swift?

chanter Fibonacci:

fib[0|1] := 1 
fib[n_Integer?Positive] := fib[n - 1] + fib[n - 2] 
fib[n__] := fib /@ {n} 
fib[n_] := "undefined" 

Voici:

In[]:= fib[10] 
Out[]= 89 

In[]:= {fib[-2], fib["2"]}  
Out[]= {"undefined", "undefined"} 

In[]:= fib[1, 2, 3, 4, 5, 6, 7] 
Out[]= {1, 2, 3, 5, 8, 13, 21} 

Est-ce rapide ont des fonctionnalités de ce genre pour les arguments basés sur des motifs ou quelque chose comme ça?

+0

S'il vous plaît rappelez-vous de marquer vos questions avec la langue. – Barmar

+0

Merci @Barmar! Désolé, je suis un débutant, devrais-je publier cet article ailleurs? –

+1

Non, c'est bien. Vous avez juste besoin de mettre 'swift' dans la liste des tags. Je l'ai déjà réparé pour vous. – Barmar

Répondre

2

Swift n'a pas de correspondance de modèle dans ses surcharges, seul le type & correspond au protocole. Le mieux que vous pouvez faire est:

func fib(n: Int) -> Int { 
    switch n { 
    case 0, 1: return 1 
    default: return fib(n - 1) + fib(n - 2) 
    } 
} 

func fib(s: [Int]) -> [Int] { 
    return s.map { fib($0) } 
} 


fib(10)   // 89 
fib([3, 4, 5]) // [3, 5, 8] 

Je vais laisser la manipulation de la saisie négative comme un exercice pour le lecteur. :)


Une version entièrement générique qui peut gérer toute entrée entière utiliserait des fonctions génériques, comme ceci:

func fib<T: IntegerType>(n: T) -> T { 
    switch n { 
    case 0, 1: return 1 
    default: return fib(n - 1) + fib(n - 2) 
    } 
} 

func fib<S: SequenceType, T : IntegerType where T == S.Generator.Element>(s: S) -> [T] { 
    return map(s) { n in 
     return fib(n) 
    } 
} 
+0

Note mineure: Les deux premiers cas pourraient être combinés à 'case 0, 1: return 1', qui ressemble un peu plus au code Mathematica donné. –

+0

(Mais je doute que la version générique est utile ici Par exemple, 'fib (Int8 (20))' se bloquerait en raison d'un débordement) –

+0

@MartinR Great points - J'ai démarré le générique en premier et utilisé 'IntegerArithmeticType', qui n'est pas littéralement convertible, mais jamais nettoyé. Fixé maintenant –

Questions connexes