1660726141
Kotlin nous oblige généralement à initialiser les propriétés dès que nous les définissons. Cela semble étrange lorsque nous ne connaissons pas la valeur initiale idéale, en particulier dans le cas des propriétés Android axées sur le cycle de vie.
Heureusement, il existe un moyen de résoudre ce problème. L'éditeur IntelliJ IDEA vous avertira si vous déclarez une propriété de classe sans l'initialiser et vous recommandera d'ajouter un mot- lateinit
clé.
Que se passe-t-il si une propriété ou un objet initialisé n'est pas réellement utilisé dans le programme ? Eh bien, ces initialisations inutilisées seront un passif pour le programme puisque la création d'objets est un processus lourd. Ceci est un autre exemple d'où lateinit
peut venir à notre secours.
Cet article explique comment le lateinit
modificateur et la délégation paresseuse peuvent prendre en charge les initialisations précoces inutilisées ou inutiles. Cela rendra votre flux de travail de développement Kotlin plus efficace.
lateinit
à KotlinLe lateinit
mot-clé signifie « initialisation tardive ». Lorsqu'il est utilisé avec une propriété de classe, le lateinit
modificateur empêche la propriété d'être initialisée au moment de la construction de l'objet de sa classe.
La mémoire est allouée aux lateinit
variables uniquement lorsqu'elles sont initialisées plus tard dans le programme, plutôt qu'au moment de leur déclaration. C'est très pratique en terme de souplesse d'initialisation.
Regardons quelques fonctionnalités importantes qui lateinit
a à offrir!
Premièrement, la mémoire n'est pas allouée à une lateinit
propriété au moment de la déclaration. L'initialisation a lieu plus tard quand bon vous semble.
Une lateinit
propriété peut changer plus d'une fois tout au long du programme et est censée être modifiable. C'est pourquoi vous devez toujours le déclarer comme a var
et non comme a val
ou const
.
L' lateinit
initialisation peut vous éviter des vérifications null répétitives dont vous pourriez avoir besoin lors de l'initialisation de propriétés en tant que types nullables. Cette fonctionnalité des lateinit
propriétés ne prend pas en charge le type nullable.
En développant mon dernier point, lateinit
peut être bien utilisé avec des types de données non primitifs. Cela ne fonctionne pas avec les types primitifs comme long
ou int
. En effet, chaque fois qu'une lateinit
propriété est accessible, Kotlin lui fournit une valeur nulle sous le capot pour indiquer que la propriété n'a pas encore été initialisée.
Les types primitifs ne peuvent pas être null
, il n'y a donc aucun moyen d'indiquer une propriété non initialisée. En conséquence, les types primitifs lèvent une exception lorsqu'ils sont utilisés avec le lateinit
mot clé.
Enfin, une lateinit
propriété doit être initialisée à un moment donné avant d'y accéder, sinon elle générera une UninitializedPropertyAccessException
erreur, comme indiqué ci-dessous :
Une lateinit
propriété accédée avant l'initialisation conduit à cette exception.
Kotlin permet de vérifier si une lateinit
propriété est initialisée. Cela peut être pratique pour gérer l'exception de désinitialisation dont nous venons de parler.
lateinit var myLateInitVar: String
...
if(::myLateInitVar.isInitialized) {
// Do something
}
lateinit
modificateurs utilisésVoyons le lateinit
modificateur en action avec un exemple simple. Le code ci-dessous définit une classe et initialise certaines de ses propriétés avec des valeurs factices et nulles.
class TwoRandomFruits {
var fruit1: String = "tomato"
var fruit2: String? = null
fun randomizeMyFruits() {
fruit1 = randomFruits()
fruit2 = possiblyNullRandomFruits()
}
fun randomFruits(): String { ... }
fun possiblyNullRandomFruits(): String? { ... }
}
fun main() {
val rf= RandomFruits()
rf.randomizeMyFruits()
println(rf.fruit1.capitalize())
println(rf.fruit2?.capitalize()) // Null-check
}
Ce n'est pas la meilleure façon d'initialiser une variable, mais dans ce cas, cela fait toujours le travail.
Comme vous pouvez le voir ci-dessus, si vous choisissez de rendre la propriété nullable, vous devrez la vérifier à chaque fois que vous la modifiez ou l'utilisez. Cela peut être assez fastidieux et ennuyeux.
Abordons ce problème avec le lateinit
modificateur :
class TwoRandomFruits {
lateinit var fruit1: String // No initial dummy value needed
lateinit var fruit2: String // Nullable type isn't supported here
fun randomizeMyFruits() {
fruit1 = randomFruits()
fruit2 = when {
possiblyNullRandomFruits() == null -> "Tomato" // Handling null values
else -> possiblyNullRandomFruits()!!
}
}
fun randomFruits(): String { ... }
fun possiblyNullRandomFruits(): String? { ... }
}
fun main() {
val rf= RandomFruits()
rf.randomizeMyFruits()
println(rf.fruit1.capitalize())
println(rf.fruit2.capitalize())
}
Vous pouvez voir ce code en action ici .
La lateinit
mise en œuvre parle d'elle-même et démontre une manière astucieuse de gérer les variables ! Outre le comportement par défaut de lateinit
, le principal point à retenir ici est la facilité avec laquelle nous pouvons éviter d'utiliser le type nullable.
lateinit
La liaison de données est un autre exemple d'utilisationlateinit
pour initialiser une activité ultérieurement. Les développeurs souhaitent souvent initialiser la variable de liaison plus tôt pour l'utiliser comme référence dans d'autres méthodes pour accéder à différentes vues.
Dans la MainActivity
classe ci-dessous, nous avons déclaré la liaison avec le lateinit
modificateur pour obtenir la même chose.
package com.test.lateinit
import androidx.appcompat.app.AppCompatActivity
import ...
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
...
}
...
}
La liaison pour MainActivity
ne peut être initialisée qu'une fois que la fonction de cycle de vie de l'activité, onCreate()
, est déclenchée. Par conséquent, déclarer la liaison avec le lateinit
modificateur prend tout son sens ici.
lateinit
Avec l'initialisation de variable régulière, vous devez ajouter une valeur fictive et, très probablement, une valeur nulle. Cela ajoutera beaucoup de vérifications nulles chaque fois qu'elles seront consultées.
// Traditional initialization
var name: String? = null
...
name = getDataFromSomeAPI()
...
// A null-check will be required whenever `name` is accessed.
name?.let { it->
println(it.uppercase())
}
// Lateinit initialization
lateinit var name: String
...
name = getDatafromSomeAPI()
...
println(name.uppercase())
Nous pouvons utiliser le lateinit
modificateur pour éviter ces vérifications nulles répétées, en particulier lorsqu'une propriété est susceptible de fluctuer fréquemment.
lateinit
Il est bon de se rappeler de toujours initialiser une lateinit
propriété avant d'y accéder, sinon, vous verrez une grosse exception levée au moment de la compilation.
Assurez-vous également de conserver la propriété modifiable en utilisant une var
déclaration. Utiliser val
et const
n'aura aucun sens, car ils indiquent des propriétés immuables avec lesquelles lateinit
ne fonctionneront pas.
Enfin, évitez d'utiliser lateinit
lorsque le type de données de la propriété donnée est primitif ou que les chances d'une valeur nulle sont élevées. Il n'est pas conçu pour ces cas et ne prend pas en charge les types primitifs ou nullables.
Comme son nom l'indique, lazy
Kotlin initialise une propriété de manière paresseuse. Essentiellement, il crée une référence mais ne va pour l'initialisation que lorsque la propriété est utilisée ou appelée pour la première fois.
Maintenant, vous vous demandez peut-être en quoi cela diffère de l'initialisation régulière. Eh bien, au moment de la construction d'un objet de classe, toutes ses propriétés publiques et privées sont initialisées dans son constructeur. Il y a une surcharge associée à l'initialisation des variables dans une classe ; plus il y a de variables, plus la surcharge sera importante.
Comprenons-le avec un exemple:
class X {
fun doThis() {}
}
class Y {
val shouldIdoThis: Boolean = SomeAPI.guide()
val x = X()
if(shouldIdoThis) {
x.doThis()
}
...
}
Bien qu'il ne l'utilise pas, class Y
dans le code ci-dessus a toujours un objet créé de class X
. La classe X
ralentira également Y
s'il s'agit d'une classe fortement construite.
La création d'objets inutiles est inefficace et peut ralentir la classe en cours. Il se peut que certaines propriétés ou certains objets ne soient pas requis dans certaines conditions, selon le déroulement du programme.
Il se peut également que des propriétés ou des objets reposent sur d'autres propriétés ou objets pour la création. La délégation paresseuse traite efficacement ces deux possibilités.
Une variable avec une initialisation différée ne sera pas initialisée tant qu'elle n'aura pas été appelée ou utilisée. De cette façon, la variable n'est initialisée qu'une seule fois, puis sa valeur est mise en cache pour une utilisation ultérieure dans le programme.
Puisqu'une propriété initialisée avec la délégation différée est censée utiliser la même valeur partout, elle est de nature immuable et est généralement utilisée pour les propriétés en lecture seule. Vous devez le marquer d'une val
déclaration.
Il est thread-safe, c'est-à-dire calculé une seule fois et partagé par tous les threads par défaut. Une fois initialisé, il se souvient ou met en cache la valeur initialisée tout au long du programme.
Contrairement à lateinit
, la délégation différée prend en charge un setter et un getter personnalisés qui lui permettent d'effectuer des opérations intermédiaires lors de la lecture et de l'écriture de la valeur.
Le code ci-dessous implémente des calculs simples pour calculer les aires de certaines formes. Dans le cas d'un cercle, le calcul nécessiterait une valeur constante pour pi
.
class Area {
val pi: Float = 3.14f
fun circle(radius: Int): Float = pi * radius * radius
fun rectangle(length: Int, breadth: Int = length): Int = length * breadth
fun triangle(base: Int, height: Int): Float = base * height * .5f
}
fun main() {
val area = Area()
val squareSideLength = 51
println("Area of our rectangle is ${area.rectangle(squareSideLength)}")
}
Comme vous pouvez le voir ci-dessus, aucun calcul de l'aire d'un cercle n'a été effectué, ce qui rend notre définition de pi
inutile. La propriété pi
est toujours initialisée et allouée de la mémoire.
Corrigeons ce problème avec la délégation paresseuse :
class Area {
val pi: Float by lazy {
3.14f
}
fun circle(...) = ...
fun rectangle(...) = ...
fun triangle(...) = ...
}
fun main() {
val area = Area()
val squareSideLength = 51
val circleRadius = 37
println("Area of our rectangle is ${area.rectangle(squareSideLength)}")
println("Area of our circle is ${area.circle(circleRadius)}")
}
Vous pouvez voir une démo de l'exemple ci-dessus ici .
L'implémentation ci-dessus de la délégation paresseuse n'est utilisée pi
que lorsqu'elle est accessible. Une fois accessible, sa valeur est mise en cache et réservée pour être utilisée tout au long du programme. Nous le verrons en action avec des objets dans les exemples suivants.
Voici comment vous pouvez ajouter des actions intermédiaires lors de l'écriture de valeurs via la délégation paresseuse. Le code ci-dessous lazy
initialise a TextView
dans une activité Android.
Chaque fois que cela TextView
est appelé pour la première fois dans le MainActivity
, un message de débogage avec une LazyInit
balise sera enregistré, comme indiqué ci-dessous dans la fonction lambda du délégué :
...
class MainActivity : AppCompatActivity() {
override fun onCreate(...) {
...
val sampleTextView: TextView by lazy {
Log.d("LazyInit", "sampleTextView")
findViewById(R.id.sampleTextView)
}
}
...
}
Passons maintenant à l'application de la délégation paresseuse dans les applications Android. Le cas d'utilisation le plus simple peut être notre exemple précédent d'une activité Android qui utilise et manipule une vue de manière conditionnelle.
package com.test.lazy
import androidx.appcompat.app.AppCompatActivity
import ...
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val sharedPrefs by lazy {
activity?
.getPreferences(Context.MODE_PRIVATE)
}
val startButton by lazy {
binding.startButton
}
if(sharedPrefs.getBoolean("firstUse", true)) {
startButton.isVisible = true
startButton.setOnClickListener {
// Finish onboarding, move to main screen; something like that
sharedPrefs.setBoolean("firstUse", false)
}
}
}
}
Ci-dessus, nous avons initialisé the SharedPreferences
et a Button
avec une délégation paresseuse. La logique implique la mise en œuvre d'un écran d'intégration basé sur une valeur booléenne extraite des préférences partagées.
by lazy
et= lazy
L' by lazy
instruction ajoute une amélioration par le délégué paresseux directement à une propriété donnée. Son initialisation ne se fera qu'une seule fois lors de son premier accès.
val prop by lazy {
...
}
D'autre part, l' = lazy
instruction contient à la place une référence à l'objet délégué, par lequel vous pouvez utiliser la isInitialized()
méthode de délégation ou y accéder avec la value
propriété.
val prop = lazy {
...
}
...
if(prop.isInitialized()) {
println(prop.value)
}
Vous pouvez voir une démo rapide du code ci-dessus ici.
lazy
Envisagez d'utiliser des délégués paresseux pour alléger une classe qui implique des créations multiples et/ou conditionnelles d'autres objets de classe. Si la création d'objet dépend d'une propriété interne de la classe, la délégation paresseuse est la solution.
class Employee {
...
fun showDetails(id: Int): List<Any> {
val employeeRecords by lazy {
EmployeeRecords(id) // Object's dependency on an internal property
}
}
...
}
lazy
L'initialisation différée est une délégation qui initialise quelque chose une seule fois et uniquement lorsqu'il est appelé. Il est destiné à éviter la création d'objets inutiles.
L'objet délégué met en cache la valeur renvoyée lors du premier accès. Cette valeur mise en cache est utilisée plus loin dans le programme si nécessaire.
Vous pouvez tirer parti de ses getter et setter personnalisés pour les actions intermédiaires lors de la lecture et de l'écriture de valeurs. Je préfère également l'utiliser avec des types immuables, car je pense que cela fonctionne mieux avec des valeurs qui restent inchangées tout au long du programme.
Dans cet article, nous avons discuté du lateinit
modificateur et de la délégation paresseuse de Kotlin. Nous avons montré quelques exemples de base démontrant leurs utilisations et avons également parlé de certains cas d'utilisation pratiques dans le développement d'Android.
Merci d'avoir pris le temps de lire cette entrée jusqu'à la fin ! J'espère que vous pourrez utiliser ce guide pour implémenter ces deux fonctionnalités dans votre parcours de développement d'applications.
Source : https://blog.logrocket.com/initializing-lazy-lateinit-variables-kotlin/
1660726141
Kotlin nous oblige généralement à initialiser les propriétés dès que nous les définissons. Cela semble étrange lorsque nous ne connaissons pas la valeur initiale idéale, en particulier dans le cas des propriétés Android axées sur le cycle de vie.
Heureusement, il existe un moyen de résoudre ce problème. L'éditeur IntelliJ IDEA vous avertira si vous déclarez une propriété de classe sans l'initialiser et vous recommandera d'ajouter un mot- lateinit
clé.
Que se passe-t-il si une propriété ou un objet initialisé n'est pas réellement utilisé dans le programme ? Eh bien, ces initialisations inutilisées seront un passif pour le programme puisque la création d'objets est un processus lourd. Ceci est un autre exemple d'où lateinit
peut venir à notre secours.
Cet article explique comment le lateinit
modificateur et la délégation paresseuse peuvent prendre en charge les initialisations précoces inutilisées ou inutiles. Cela rendra votre flux de travail de développement Kotlin plus efficace.
lateinit
à KotlinLe lateinit
mot-clé signifie « initialisation tardive ». Lorsqu'il est utilisé avec une propriété de classe, le lateinit
modificateur empêche la propriété d'être initialisée au moment de la construction de l'objet de sa classe.
La mémoire est allouée aux lateinit
variables uniquement lorsqu'elles sont initialisées plus tard dans le programme, plutôt qu'au moment de leur déclaration. C'est très pratique en terme de souplesse d'initialisation.
Regardons quelques fonctionnalités importantes qui lateinit
a à offrir!
Premièrement, la mémoire n'est pas allouée à une lateinit
propriété au moment de la déclaration. L'initialisation a lieu plus tard quand bon vous semble.
Une lateinit
propriété peut changer plus d'une fois tout au long du programme et est censée être modifiable. C'est pourquoi vous devez toujours le déclarer comme a var
et non comme a val
ou const
.
L' lateinit
initialisation peut vous éviter des vérifications null répétitives dont vous pourriez avoir besoin lors de l'initialisation de propriétés en tant que types nullables. Cette fonctionnalité des lateinit
propriétés ne prend pas en charge le type nullable.
En développant mon dernier point, lateinit
peut être bien utilisé avec des types de données non primitifs. Cela ne fonctionne pas avec les types primitifs comme long
ou int
. En effet, chaque fois qu'une lateinit
propriété est accessible, Kotlin lui fournit une valeur nulle sous le capot pour indiquer que la propriété n'a pas encore été initialisée.
Les types primitifs ne peuvent pas être null
, il n'y a donc aucun moyen d'indiquer une propriété non initialisée. En conséquence, les types primitifs lèvent une exception lorsqu'ils sont utilisés avec le lateinit
mot clé.
Enfin, une lateinit
propriété doit être initialisée à un moment donné avant d'y accéder, sinon elle générera une UninitializedPropertyAccessException
erreur, comme indiqué ci-dessous :
Une lateinit
propriété accédée avant l'initialisation conduit à cette exception.
Kotlin permet de vérifier si une lateinit
propriété est initialisée. Cela peut être pratique pour gérer l'exception de désinitialisation dont nous venons de parler.
lateinit var myLateInitVar: String
...
if(::myLateInitVar.isInitialized) {
// Do something
}
lateinit
modificateurs utilisésVoyons le lateinit
modificateur en action avec un exemple simple. Le code ci-dessous définit une classe et initialise certaines de ses propriétés avec des valeurs factices et nulles.
class TwoRandomFruits {
var fruit1: String = "tomato"
var fruit2: String? = null
fun randomizeMyFruits() {
fruit1 = randomFruits()
fruit2 = possiblyNullRandomFruits()
}
fun randomFruits(): String { ... }
fun possiblyNullRandomFruits(): String? { ... }
}
fun main() {
val rf= RandomFruits()
rf.randomizeMyFruits()
println(rf.fruit1.capitalize())
println(rf.fruit2?.capitalize()) // Null-check
}
Ce n'est pas la meilleure façon d'initialiser une variable, mais dans ce cas, cela fait toujours le travail.
Comme vous pouvez le voir ci-dessus, si vous choisissez de rendre la propriété nullable, vous devrez la vérifier à chaque fois que vous la modifiez ou l'utilisez. Cela peut être assez fastidieux et ennuyeux.
Abordons ce problème avec le lateinit
modificateur :
class TwoRandomFruits {
lateinit var fruit1: String // No initial dummy value needed
lateinit var fruit2: String // Nullable type isn't supported here
fun randomizeMyFruits() {
fruit1 = randomFruits()
fruit2 = when {
possiblyNullRandomFruits() == null -> "Tomato" // Handling null values
else -> possiblyNullRandomFruits()!!
}
}
fun randomFruits(): String { ... }
fun possiblyNullRandomFruits(): String? { ... }
}
fun main() {
val rf= RandomFruits()
rf.randomizeMyFruits()
println(rf.fruit1.capitalize())
println(rf.fruit2.capitalize())
}
Vous pouvez voir ce code en action ici .
La lateinit
mise en œuvre parle d'elle-même et démontre une manière astucieuse de gérer les variables ! Outre le comportement par défaut de lateinit
, le principal point à retenir ici est la facilité avec laquelle nous pouvons éviter d'utiliser le type nullable.
lateinit
La liaison de données est un autre exemple d'utilisationlateinit
pour initialiser une activité ultérieurement. Les développeurs souhaitent souvent initialiser la variable de liaison plus tôt pour l'utiliser comme référence dans d'autres méthodes pour accéder à différentes vues.
Dans la MainActivity
classe ci-dessous, nous avons déclaré la liaison avec le lateinit
modificateur pour obtenir la même chose.
package com.test.lateinit
import androidx.appcompat.app.AppCompatActivity
import ...
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
...
}
...
}
La liaison pour MainActivity
ne peut être initialisée qu'une fois que la fonction de cycle de vie de l'activité, onCreate()
, est déclenchée. Par conséquent, déclarer la liaison avec le lateinit
modificateur prend tout son sens ici.
lateinit
Avec l'initialisation de variable régulière, vous devez ajouter une valeur fictive et, très probablement, une valeur nulle. Cela ajoutera beaucoup de vérifications nulles chaque fois qu'elles seront consultées.
// Traditional initialization
var name: String? = null
...
name = getDataFromSomeAPI()
...
// A null-check will be required whenever `name` is accessed.
name?.let { it->
println(it.uppercase())
}
// Lateinit initialization
lateinit var name: String
...
name = getDatafromSomeAPI()
...
println(name.uppercase())
Nous pouvons utiliser le lateinit
modificateur pour éviter ces vérifications nulles répétées, en particulier lorsqu'une propriété est susceptible de fluctuer fréquemment.
lateinit
Il est bon de se rappeler de toujours initialiser une lateinit
propriété avant d'y accéder, sinon, vous verrez une grosse exception levée au moment de la compilation.
Assurez-vous également de conserver la propriété modifiable en utilisant une var
déclaration. Utiliser val
et const
n'aura aucun sens, car ils indiquent des propriétés immuables avec lesquelles lateinit
ne fonctionneront pas.
Enfin, évitez d'utiliser lateinit
lorsque le type de données de la propriété donnée est primitif ou que les chances d'une valeur nulle sont élevées. Il n'est pas conçu pour ces cas et ne prend pas en charge les types primitifs ou nullables.
Comme son nom l'indique, lazy
Kotlin initialise une propriété de manière paresseuse. Essentiellement, il crée une référence mais ne va pour l'initialisation que lorsque la propriété est utilisée ou appelée pour la première fois.
Maintenant, vous vous demandez peut-être en quoi cela diffère de l'initialisation régulière. Eh bien, au moment de la construction d'un objet de classe, toutes ses propriétés publiques et privées sont initialisées dans son constructeur. Il y a une surcharge associée à l'initialisation des variables dans une classe ; plus il y a de variables, plus la surcharge sera importante.
Comprenons-le avec un exemple:
class X {
fun doThis() {}
}
class Y {
val shouldIdoThis: Boolean = SomeAPI.guide()
val x = X()
if(shouldIdoThis) {
x.doThis()
}
...
}
Bien qu'il ne l'utilise pas, class Y
dans le code ci-dessus a toujours un objet créé de class X
. La classe X
ralentira également Y
s'il s'agit d'une classe fortement construite.
La création d'objets inutiles est inefficace et peut ralentir la classe en cours. Il se peut que certaines propriétés ou certains objets ne soient pas requis dans certaines conditions, selon le déroulement du programme.
Il se peut également que des propriétés ou des objets reposent sur d'autres propriétés ou objets pour la création. La délégation paresseuse traite efficacement ces deux possibilités.
Une variable avec une initialisation différée ne sera pas initialisée tant qu'elle n'aura pas été appelée ou utilisée. De cette façon, la variable n'est initialisée qu'une seule fois, puis sa valeur est mise en cache pour une utilisation ultérieure dans le programme.
Puisqu'une propriété initialisée avec la délégation différée est censée utiliser la même valeur partout, elle est de nature immuable et est généralement utilisée pour les propriétés en lecture seule. Vous devez le marquer d'une val
déclaration.
Il est thread-safe, c'est-à-dire calculé une seule fois et partagé par tous les threads par défaut. Une fois initialisé, il se souvient ou met en cache la valeur initialisée tout au long du programme.
Contrairement à lateinit
, la délégation différée prend en charge un setter et un getter personnalisés qui lui permettent d'effectuer des opérations intermédiaires lors de la lecture et de l'écriture de la valeur.
Le code ci-dessous implémente des calculs simples pour calculer les aires de certaines formes. Dans le cas d'un cercle, le calcul nécessiterait une valeur constante pour pi
.
class Area {
val pi: Float = 3.14f
fun circle(radius: Int): Float = pi * radius * radius
fun rectangle(length: Int, breadth: Int = length): Int = length * breadth
fun triangle(base: Int, height: Int): Float = base * height * .5f
}
fun main() {
val area = Area()
val squareSideLength = 51
println("Area of our rectangle is ${area.rectangle(squareSideLength)}")
}
Comme vous pouvez le voir ci-dessus, aucun calcul de l'aire d'un cercle n'a été effectué, ce qui rend notre définition de pi
inutile. La propriété pi
est toujours initialisée et allouée de la mémoire.
Corrigeons ce problème avec la délégation paresseuse :
class Area {
val pi: Float by lazy {
3.14f
}
fun circle(...) = ...
fun rectangle(...) = ...
fun triangle(...) = ...
}
fun main() {
val area = Area()
val squareSideLength = 51
val circleRadius = 37
println("Area of our rectangle is ${area.rectangle(squareSideLength)}")
println("Area of our circle is ${area.circle(circleRadius)}")
}
Vous pouvez voir une démo de l'exemple ci-dessus ici .
L'implémentation ci-dessus de la délégation paresseuse n'est utilisée pi
que lorsqu'elle est accessible. Une fois accessible, sa valeur est mise en cache et réservée pour être utilisée tout au long du programme. Nous le verrons en action avec des objets dans les exemples suivants.
Voici comment vous pouvez ajouter des actions intermédiaires lors de l'écriture de valeurs via la délégation paresseuse. Le code ci-dessous lazy
initialise a TextView
dans une activité Android.
Chaque fois que cela TextView
est appelé pour la première fois dans le MainActivity
, un message de débogage avec une LazyInit
balise sera enregistré, comme indiqué ci-dessous dans la fonction lambda du délégué :
...
class MainActivity : AppCompatActivity() {
override fun onCreate(...) {
...
val sampleTextView: TextView by lazy {
Log.d("LazyInit", "sampleTextView")
findViewById(R.id.sampleTextView)
}
}
...
}
Passons maintenant à l'application de la délégation paresseuse dans les applications Android. Le cas d'utilisation le plus simple peut être notre exemple précédent d'une activité Android qui utilise et manipule une vue de manière conditionnelle.
package com.test.lazy
import androidx.appcompat.app.AppCompatActivity
import ...
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val sharedPrefs by lazy {
activity?
.getPreferences(Context.MODE_PRIVATE)
}
val startButton by lazy {
binding.startButton
}
if(sharedPrefs.getBoolean("firstUse", true)) {
startButton.isVisible = true
startButton.setOnClickListener {
// Finish onboarding, move to main screen; something like that
sharedPrefs.setBoolean("firstUse", false)
}
}
}
}
Ci-dessus, nous avons initialisé the SharedPreferences
et a Button
avec une délégation paresseuse. La logique implique la mise en œuvre d'un écran d'intégration basé sur une valeur booléenne extraite des préférences partagées.
by lazy
et= lazy
L' by lazy
instruction ajoute une amélioration par le délégué paresseux directement à une propriété donnée. Son initialisation ne se fera qu'une seule fois lors de son premier accès.
val prop by lazy {
...
}
D'autre part, l' = lazy
instruction contient à la place une référence à l'objet délégué, par lequel vous pouvez utiliser la isInitialized()
méthode de délégation ou y accéder avec la value
propriété.
val prop = lazy {
...
}
...
if(prop.isInitialized()) {
println(prop.value)
}
Vous pouvez voir une démo rapide du code ci-dessus ici.
lazy
Envisagez d'utiliser des délégués paresseux pour alléger une classe qui implique des créations multiples et/ou conditionnelles d'autres objets de classe. Si la création d'objet dépend d'une propriété interne de la classe, la délégation paresseuse est la solution.
class Employee {
...
fun showDetails(id: Int): List<Any> {
val employeeRecords by lazy {
EmployeeRecords(id) // Object's dependency on an internal property
}
}
...
}
lazy
L'initialisation différée est une délégation qui initialise quelque chose une seule fois et uniquement lorsqu'il est appelé. Il est destiné à éviter la création d'objets inutiles.
L'objet délégué met en cache la valeur renvoyée lors du premier accès. Cette valeur mise en cache est utilisée plus loin dans le programme si nécessaire.
Vous pouvez tirer parti de ses getter et setter personnalisés pour les actions intermédiaires lors de la lecture et de l'écriture de valeurs. Je préfère également l'utiliser avec des types immuables, car je pense que cela fonctionne mieux avec des valeurs qui restent inchangées tout au long du programme.
Dans cet article, nous avons discuté du lateinit
modificateur et de la délégation paresseuse de Kotlin. Nous avons montré quelques exemples de base démontrant leurs utilisations et avons également parlé de certains cas d'utilisation pratiques dans le développement d'Android.
Merci d'avoir pris le temps de lire cette entrée jusqu'à la fin ! J'espère que vous pourrez utiliser ce guide pour implémenter ces deux fonctionnalités dans votre parcours de développement d'applications.
Source : https://blog.logrocket.com/initializing-lazy-lateinit-variables-kotlin/
1621508255
We are a prime Kotlin app developer in India. We build and provide the best personalized Android apps, migration services, ongoing maintenance, and management.
We have the most efficient Kotlin developers that build ultramodern, interactive, and secure mobile apps. The technologies we use to create the most advanced Kotlin apps are AR/VR, AI/ML, IoT, etc.
Hire Kotlin app developers in India. Meet us, and we will help you meet all of your technology requirements.
#kotlin app development company india #hire kotlin developers india #kotlin app development company #hire kotlin developers #kotlin development agency #kotlin app programmers
1616586592
The most popular language used for Android app development is Kotlin and recently Kotlin also launched its Cross-Platform app development language Kotlin Multiplatform.
So are you looking to launch a mobile using Kotlin as your Programming Language?
Then you are at the right place as WebClues Infotech offers services to Hire a Dedicated Kotlin Developer who can develop an interactive and rich user-experienced mobile app. Also, WebClues has a flexible pricing model that the business can choose according to its most suitable structure.
So what are you waiting for? Hire a dedicated Kotlin developer from a reputed Web & Mobile app development agency that has successfully served more than 600+ clients.
Book Free Interview: https://bit.ly/3dDShFg
#hire dedicated kotlin developer #hire dedicated kotlin developer #hire kotlin developers #hire kotlin developer #hire dedicated kotlin app developer #hire kotlin app developers india
1609415481
Do you have an idea to develop an android app using Kotlin?
Are you looking for the best Kotlin app development company in the USA? We at AppClues Infotech offering versatile mobile app development services in the USA. We provide custom mobile app development solutions as per your specific business needs with the prevailing market trending technology & features.
Hire our top-notch Kotlin app designers & developers for your project at a cost-effective price.
Our Kotlin App Development Services:
• Custom Android App Development
• Kotlin AR/VR App Development
• Kotlin App UI/UX Design
• Kotlin App QA & Testing- code Optimization
• Kotlin App Migrations
• Kotlin App Maintenance and Upgrades
For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910
#kotlin android app development company #best kotlin android app development usa #kotlin android app development #kotlin for android app development #kotlin mobile app development service #create android app with kotlin
1606541075
Looking for a top Kotlin Android app development company for creating an Android app project? AppClues Infotech is a top Kotlin Android app development company in USA that delivers the most scalable and efficient Kotlin app development services globally.
For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910
#kotlin android app development company #best kotlin android app development usa #kotlin android app development #kotlin for android app development #kotlin mobile app development service #create android app with kotlin