Le système de types de Kotlin est un type qui peut être nul,
Distinguer les types qui ne peuvent pas l'être.
Pour les types qui peuvent être null, ajoutez ?
Après le nom du type.
val num: Int = null //L'erreur de compilation ne peut pas être nulle
val num: Int? = null //OK si le type Nullable
Vous ne pouvez pas accéder directement aux fonctions et propriétés à tolérance nulle. Une erreur de compilation se produira.
val num: Int? = null //Déclaré comme type Nullable
val floatNum = num.toFloat() //Erreur de compilation
Inaccessible s'il peut être nul signifie Le risque de NullPointerException est considérablement réduit.
Vous verrez souvent de telles vérifications nulles en Java.
// Java
Dog dog = //Peut être nul
dog.run(); //Possible NullPointerException Ali
if (dog != null) {
dog.run(); //Null vérifié
}
Implémentons la même chose avec Kotlin.
val dog: Dog? = //Peut être nul
dog.run() //Erreur de compilation
if (dog != null) {
dog.run() //OK pour les blocs vérifiés par zéro
}
Les fonctions des objets à tolérance nulle ne peuvent pas être appelées directement. Transtypage automatique en type non autorisé null dans null coché si bloc Vous pouvez appeler la fonction. C'est ce qu'on appelle une distribution intelligente.
Kotlin a également une syntaxe d'enrobage de sucre plus pratique.
val dog: Dog? = //Peut être nul
dog?.run()
Vous pouvez accéder aux appels de fonction et aux propriétés après ? .
.
Dans l'exemple ci-dessus, si «dog» est nul, il renvoie simplement nul.
C'est ce qu'on appelle un appel sécurisé.
Vous verrez un code abattu comme celui-ci en Java.
/*
*La classe de chien est une sous-classe de la classe animale
*/
Animal animal = // ...
((Dog)animal).run(); //Possibilité de ClassCastException Ali
if (animal instanceof Dog) {
Dog dog = (Dog)animal;
dog.run();
}
Implémentons la même chose avec Kotlin.
/*
*La classe de chien est une sous-classe de la classe animale
*/
val animal: Animal = // ...
(animal as Dog).run() // //Possibilité de ClassCastException Ali
if (animal is Dog) {
animal.run()
}
Les casts de Kotlin utilisent l'opérateur ʻas`. Si la conversion échoue, une ClassCastException sera levée.
L'équivalent Java de ʻinstanceof est l'opérateur ʻis
.
C'est aussi par smart cast
Dans le bloc if, la variable ʻanimal` est automatiquement convertie en type Dog,
Vous pouvez appeler la méthode de la classe Dog telle quelle.
Kotlin a également une syntaxe d'enrobage de sucre plus pratique.
val animal: Animal = // ...
(animal as? Dog)?.run()
L'opérateur ʻas? ʻ le lance dans le typeDog?
Dans l'exemple ci-dessus.
S'il ne peut pas être casté, il retournera null, ce qui est sûr.
Outre l'appel sécurisé (avec .?
), Il existe un moyen de gérer les types tolérants à zéro.
val num: Int? = //Peut être nul
val floatNum = num.toFloat() //Erreur de compilation
val floatNum = num!!.toFloat() //Compilez OK mais possible NullPointerException
Ajoutez . !!
.
Il y a des situations où cela est nécessaire, mais il ne doit pas être utilisé autant que possible.
Vous verrez souvent ce type de branchement en Java.
// Java
Dog dog = getDog(); //La valeur de retour de getDog peut être nulle
if (dog == null) {
dog = new Dog();
}
dog.run();
kotlin a un opérateur qui est utile quand "s'il est nul".
val dog = getDog() ?: Dog()
dog.run()
?:
Opérateur Elvis
Variables à tolérance nulle sur la gauche
Sur le côté droit, décrivez le processus à exécuter s'il est nul.
Il est courant de créer des objets alternatifs et de lancer des exceptions.
Lors de la déclaration d'une propriété d'une classe, vous devrez peut-être en faire un type Nullable. Classes de framework qui ne peuvent pas remplacer les constructeurs, Propriétés qui ne peuvent être initialisées qu'après un certain rappel ...
Cependant, ils sont généralement difficiles à utiliser avec des types à tolérance nulle, et vous souhaiterez peut-être les traiter pratiquement de types à tolérance nulle. (Souvent développé avec Kotlin)
Dans un tel cas, le modificateur "lateinit" est pratique.
//Afficher la classe pour la connexion
class LoginView {
//Il a des éléments enfants tels que TextView et Button,
//Ceux-ci sont générés à partir de ressources...Système d'interface utilisateur virtuelle
lateinit var emailTextView: TextView
lateinit var passwordTextView: TextView
lateinit var loginButton: Button
//Les éléments enfants peuvent être récupérés lorsque View est chargé à partir d'une ressource
fun onLoadViewFromResource(viewResource: View) {
this.emailTextView = viewResource.children[0]
this.passwordTextView = viewResource.children[1]
this.loginButton = viewResource.children[2]
}
}
Le modificateur lateinit
peut retarder l'initialisation,
Notez que l'accès à la propriété avant l'initialisation entraînera une exception.
En plus de cela, il existe un délégué de propriété appelé «paresseux». Ceci est utile pour l'initialisation différée de propriétés dont l'initialisation est coûteuse.
class LoginView {
val loginConnection: LoginConnection by lazy {
LoginConnection() //La connexion est coûteuse à générer
}
}
Recommended Posts