Explication d'une partie d'un code
helio
Membre
Bonjour à tous,
Dans le code du lien ci-après : https://pbs.twimg.com/media/Dq0u-EFXgAACI3H?format=jpg&name=large
Quelle est la signification de l'instruction suivante, et plus précisément le "=()" :
typealias Provider<T> = () -> T
merci
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
J'aurais dit closure sans paramètre qui renvoie un objet de "type T" (après c'est du générique).
C'est intéressant comme question parce que c'est un code tout bête qui appelle à tout un tas de concepts propres à Swift.
On commence par la définition en elle-même.
typealias
permet de définir un type simple à partir d'un type plus complexe ou composé. Explications:Provider<T>
défini un type générique qui capture un autre typeT
au moment de la compilation.() -> T
défini une closure —qui est typiquement le type d'une fonction pour simplifier— qui ne prend pas de paramètre d'entrée et renvoie un objet de typeT
... Bizarre...Si on avait créé une fonction f avec cette signature on aurait fait ça :
func f<T>() -> T
. Une fonction générique, exactement.Reste maintenant ce problème de
T
qu'est-ce qu'on en fait ? Swift nous permet de le spécifier explicitement ou de l'inférer. ConsidéronsProvider<T>
pour le moment il n'a pas de typeT
défini, il est donc générique. Spécialisons-le :let intProvider: Provider<Int> = { return 1 }
Ici on vient de créer une closure
intProvider
qui ne prends pas de paramètre en entrée mais qui renvoie unInt
. On peut faire pareil et lui dire de renvoyer unCGFloat
:let intProvider: Provider<CGFloat> = { return 1 }
.On commence à y voir plus clair. Mais qu'est-ce qui se passe si on laisse le compilateur inférer notre type
T
? Dans ce cas-ci ça va être compliqué pour tout un tas de raisons. Mais il y a un caslet stringProvider: Provider = { return "str" }
. Ici on ne spécifie pasT
il est inféré par le type du retour de la closure.En réalité ce genre de
typealias
n'as pas un grand intérêt fonctionnel c'est surtout du syntactic sugar parce que c'est plus beau et plus lisible d'écrireinit(provider: Provider<Set<String>>)
plutôt queinit(provider: () -> Set<String>)
. Ah non ?Alors on peut aussi faire ça
typealias StringSetProvider = Provider<Set<String>>
et làinit(provider: StringSetProvider)
est agréable à l'oeil 😉)Merci pour les explications !
J'avais déjà du mal a digérer les closures, pour le coup c'est une indigestion cette fois... mais bon