Dans la session Introduction à Swift WWDC, une propriété en lecture seule description
est démontrée:
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
Y a-t-il des implications à choisir l'approche ci-dessus plutôt que d'utiliser une méthode à la place:
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
Il me semble que les raisons les plus évidentes pour lesquelles vous choisiriez une propriété calculée en lecture seule sont:
- Sémantique - dans cet exemple, il est logique
description
d'être une propriété de la classe plutôt qu'une action qu'elle effectue. - Brevity / Clarté - évite d'avoir à utiliser des parenthèses vides lors de l'obtention de la valeur.
Il est clair que l'exemple ci-dessus est trop simple, mais y a-t-il d'autres bonnes raisons de choisir l'un plutôt que l'autre? Par exemple, y a-t-il des caractéristiques de fonctions ou de propriétés qui vous guideraient dans votre décision d'utiliser?
NB À première vue, cela semble être une question OOP assez courante, mais je suis impatient de connaître toutes les fonctionnalités spécifiques à Swift qui guideraient les meilleures pratiques lors de l'utilisation de ce langage.
la source
get {}
? Je ne savais pas ça, merci!Réponses:
Il me semble que c'est surtout une question de style: je préfère fortement utiliser des propriétés pour cela: propriétés; ce qui signifie des valeurs simples que vous pouvez obtenir et / ou définir. J'utilise des fonctions (ou des méthodes) lorsque le travail est en cours. Peut-être que quelque chose doit être calculé ou lu à partir du disque ou d'une base de données: dans ce cas, j'utilise une fonction, même si seule une valeur simple est renvoyée. De cette façon, je peux facilement voir si un appel est bon marché (propriétés) ou éventuellement cher (fonctions).
Nous obtiendrons probablement plus de clarté lorsque Apple publiera certaines conventions de codage Swift.
la source
Eh bien, vous pouvez appliquer les conseils de Kotlin https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties .
la source
Bien qu'une question de propriétés calculées par rapport aux méthodes en général soit difficile et subjective, il existe actuellement un argument important dans le cas de Swift pour préférer les méthodes aux propriétés. Vous pouvez utiliser des méthodes dans Swift comme des fonctions pures, ce qui n'est pas vrai pour les propriétés (à partir de Swift 2.0 beta). Cela rend les méthodes beaucoup plus puissantes et utiles puisqu'elles peuvent participer à la composition fonctionnelle.
la source
Le runtime étant le même, cette question s'applique également à Objective-C. Je dirais, avec les propriétés que vous obtenez
readwrite
didSet
pour les notifications de changementQuant à quelque chose de spécifique à Swift, le seul exemple que j'ai est que vous pouvez l'utiliser
@lazy
pour une propriété.la source
Il y a une différence: si vous utilisez une propriété, vous pouvez éventuellement la remplacer et la faire lire / écrire dans une sous-classe.
la source
willSet
etdidSet
à la classe de base , sans rien savoir des futures classes dérivées, peut détecter les changements dans la propriété substituée. Mais vous ne pouvez rien faire de tel avec des fonctions, je pense.Dans le cas en lecture seule, une propriété calculée ne doit pas être considérée comme sémantiquement équivalente à une méthode, même lorsqu'elle se comporte de manière identique, car l'abandon de la
func
déclaration brouille la distinction entre les quantités qui composent l' état d'une instance et les quantités qui ne sont que des fonctions du Etat. Vous enregistrez la saisie()
sur le site d'appel, mais vous risquez de perdre la clarté de votre code.À titre d'exemple trivial, considérons le type de vecteur suivant:
En déclarant la longueur comme une méthode, il est clair que c'est une fonction de l'état, qui ne dépend que de
x
ety
.D'autre part, si vous deviez exprimer
length
comme une propriété calculéepuis quand vous remplissez-tab-point dans votre IDE sur une instance de
VectorWithLengthAsProperty
, il ressemblerait comme six
,y
,length
étaient des propriétés sur un pied d' égalité, ce qui est incorrect sur le plan conceptuel.la source
Il existe des situations où vous préféreriez la propriété calculée aux fonctions normales. Tels que: renvoyer le nom complet d'une personne. Vous connaissez déjà le prénom et le nom. Donc vraiment la
fullName
propriété est une propriété pas une fonction. Dans ce cas, il s'agit d'une propriété calculée (car vous ne pouvez pas définir le nom complet, vous pouvez simplement l'extraire en utilisant le prénom et le nom)la source
Du point de vue des performances, il ne semble pas y avoir de différence. Comme vous pouvez le voir dans le résultat de référence.
essentiel
main.swift
extrait de code:Production:
prop: 0.0380070209503174 func: 0.0350250005722046 prop: 0.371925950050354 func: 0.363085985183716 prop: 3.4023300409317 func: 3.38373708724976 prop: 33.5842199325562 func: 34.8433820009232 Program ended with exit code: 0
Dans le graphique:
la source
Date()
ne convient pas aux benchmarks car il utilise l'horloge de l'ordinateur, qui est soumise à des mises à jour automatiques par le système d'exploitation.mach_absolute_time
obtiendrait des résultats plus fiables.Sémantiquement parlant, les propriétés calculées doivent être étroitement associées à l'état intrinsèque de l'objet - si les autres propriétés ne changent pas, l'interrogation de la propriété calculée à des moments différents devrait donner le même résultat (comparable via == ou ===) - similaire pour appeler une fonction pure sur cet objet.
D'autre part, les méthodes sortent de la boîte avec l'hypothèse que nous n'obtenons pas toujours les mêmes résultats, car Swift n'a pas de moyen de marquer les fonctions comme pures. De plus, les méthodes de la POO sont considérées comme des actions, ce qui signifie que leur exécution peut entraîner des effets secondaires. Si la méthode n'a pas d'effets secondaires, elle peut être convertie en toute sécurité en propriété calculée.
Notez que les deux déclarations ci-dessus sont purement d'un point de vue sémantique, car il pourrait bien arriver que les propriétés calculées aient des effets secondaires auxquels nous ne nous attendons pas et que les méthodes soient pures.
la source
Historiquement, la description est une propriété sur NSObject et beaucoup s'attendent à ce qu'elle continue de la même manière dans Swift. Ajouter des parens après cela ne fera qu'ajouter de la confusion.
EDIT: Après un vote négatif furieux, je dois clarifier quelque chose - s'il est accédé via la syntaxe dot, cela peut être considéré comme une propriété. Peu importe ce qu'il y a sous le capot. Vous ne pouvez pas accéder aux méthodes habituelles avec la syntaxe dot.
De plus, appeler cette propriété ne nécessitait pas de parens supplémentaires, comme dans le cas de Swift, ce qui peut prêter à confusion.
la source
description
est une méthode requise sur leNSObject
protocole, et donc dans objective-C est retourné en utilisant[myObject description]
. Quoi qu'il en soit, la propriétédescription
était simplement un exemple artificiel - je recherche une réponse plus générique qui s'applique à toute propriété / fonction personnalisée.