Je suppose que ce que vous essayez de faire est de générer paresseusement la valeur par défaut pour une propriété inscriptible . Je trouve souvent que les gens sautent à la paresse quand ce n'est pas nécessaire. Assurez-vous que cela vaut vraiment la peine. Cela ne vaudrait le coup que si la valeur par défaut est rarement utilisée, mais assez chère à créer. Mais si c'est votre situation, c'est une façon de le faire.
lazy
implémente un motif très spécifique et assez limité qui n'est souvent pas ce que vous voulez. (Il n'est pas du tout certain que lazy
était un ajout précieux au langage étant donné son fonctionnement, et il y a un travail actif pour le remplacer par un système d'attributs beaucoup plus puissant et utile.) Quand lazy
n'est pas l'outil que vous voulez, vous venez de construire votre propre. Dans votre exemple, il ressemblerait à ceci:
private var _pi: Double?
var pi: Double {
get {
if let pi = _pi { return pi }
let result = // calculations....
_pi = result
return result
}
set { _pi = newValue }
}
Cela dit, dans la plupart des cas, je l'ai vu venir, il est préférable d'utiliser une valeur par défaut dans INIT:
func computePi() -> Double {
// compute and return value
}
// This is global. Globals are lazy (in a thread-safe way) automatically.
let computedPi = computePi()
struct X {
let pi: Double // I'm assuming it was var only because it might be overridden
init(pi: Double = computedPi) {
self.pi = pi
}
}
Le faire de cette façon calcule pi une seule fois dans le programme entier (plutôt qu'une fois par instance). Et il nous permet de faire pi
"write-exactement-une fois" plutôt que l'état mutable. (Cela peut correspondre ou non à vos besoins, s'il faut vraiment écrire, alors var
.)
Une approche similaire à la valeur par défaut peut être utilisée pour des objets coûteux à construire (plutôt que des objets statiques qui sont chers à calculer) sans avoir besoin d'un global.
struct X {
let pi: Double
init(pi: ExpensiveObject = ExpensiveObject()) {
self.pi = pi
}
}
Mais parfois, les getters et les setters conviennent mieux.
pourquoi avez-vous besoin de cela? Y a-t-il une raison spécifique? – karthikeyan
1. Ce ne sont pas des fermetures 2. Le getter ne fonctionnera pas tant qu'il n'aura pas été appelé. Qu'est-ce que vous essayez d'accomplir? –
Comment anticipez-vous cela fonctionne? Avec une propriété paresseuse, elle est définie au premier accès. Avec un setter, il est réglé dès que le setter est utilisé. Voulez-vous un getter paresseux par défaut et un setter explicite? S'il vous plaît ajouter plus de détails. – ColGraff