Kotlin From Scratch Packages et fonctions de base

Kotlin est un langage de programmation moderne qui compile en bytecode Java. C'est gratuit et open source, et promet de rendre le codage pour Android encore plus amusant. 

Dans l'article précédent, vous avez découvert les gammes et les collections de Kotlin. Dans ce didacticiel, nous allons continuer à apprendre le langage en examinant comment organiser le code à l'aide de packages, puis une introduction aux fonctions de Kotlin..

1. Forfaits

Si vous connaissez Java, vous savez que Java utilise des packages pour regrouper des classes liées. par exemple, le java.util package contient un certain nombre de classes d’utilitaires utiles. Les colis sont déclarés avec le paquet mot-clé, et tout fichier Kotlin avec un paquet déclaration au début peut contenir des déclarations de classes, fonctions ou interfaces.

Déclaration

En regardant le code ci-dessous, nous avons déclaré un paquet com.chikekotlin.projectx en utilisant le paquet mot-clé. En outre, nous avons déclaré une classe Ma classe (nous discuterons des cours dans Kotlin dans les prochains articles) à l'intérieur de ce paquet.

paquet com.chikekotlin.projectx classe MyClass

Maintenant, le nom complet de la classe Ma classe est com.chikekotlin.projectx.MyClass.

paquet com.chikekotlin.projectx fun saySomething (): String return "How far?" 

Dans le code ci-dessus, nous avons créé une fonction de niveau supérieur (nous y reviendrons dans un instant). Tellement semblable à Ma classe, le nom complet de la fonction dis quelquechose() est com.chikekotlin.projectx.sayQuelque chose.

Importations

À Kotlin, nous utilisons le importation déclaration permettant au compilateur de localiser les classes, fonctions, interfaces ou objets à importer. En revanche, en Java, nous ne pouvons pas importer directement des fonctions ou des classes ou interfaces exclusivement de méthodes.. 

Nous utilisons importation pour accéder à une fonction, une interface, une classe ou un objet en dehors du package où il a été déclaré. 

importer com.chikekotlin.projectx.sayQuelque chose d'amusant (args: Array) sayQuelque chose () // affichera "Jusqu'où?" 

Dans l'extrait de code ci-dessus, nous avons importé la fonction dis quelquechose() à partir d'un autre package, puis nous avons exécuté cette fonction.

Kotlin prend également en charge les importations de caractères génériques à l'aide du * opérateur. Cela importera toutes les classes, interfaces et fonctions déclarées dans le paquet en même temps. Ceci n'est pas recommandé, cependant, il est généralement préférable de rendre vos importations explicites..

importer com.chikekotlin.projectx. *

Aliasing d'importation

Lorsque des bibliothèques ont des noms de classe ou de fonction en conflit (par exemple, elles déclarent chacune une fonction du même nom), vous pouvez utiliser le comme mot clé pour donner à cette entité importée un nom temporaire.

import com.chikekotlin.projectx.sayQuelque chose import com.chikekotlin.projecty.sayQuelque chose comme projetYSayQuelque chose d'amusant (args: Array) projectYSayQuelque chose ()

Notez que le nom temporaire est utilisé uniquement dans le fichier où il a été attribué..

2. fonctions

Une fonction regroupe une série d'instructions de code permettant d'exécuter une tâche. Les détails de l'implémentation de la fonction sont cachés à l'appelant..

En Kotlin, les fonctions sont définies à l'aide du amusement comme indiqué dans l'exemple suivant:

fun hello (name: String): String return "Hello $ name" val message = hello ("Chike") print (message) // affichera "Hello Chike"

Dans le code ci-dessus, nous avons défini une fonction simple Bonjour() avec un seul paramètre prénom de type Chaîne. Cette fonction retourne un Chaîne type. Le format de définition des paramètres pour les fonctions est nom: type, par exemple. âge: Int, prix: Double, étudiant: StudentClass.

fun hello (name: String): Unit print ("Hello $ name") hello ("Chike") // affichera "Hello Chike"

La fonction ci-dessus est similaire à la précédente, mais notez que celle-ci a un type de retour de Unité. Parce que cette fonction ne nous renvoie aucune valeur significative - elle imprime simplement un message - son type de retour est Unité par défaut. Unité est un objet Kotlin (nous discuterons des objets Kotlin dans des publications ultérieures) similaire au Vide types en Java et C.

objet public Unit override fun toString () = "kotlin.Unit"

Notez que si vous ne déclarez pas explicitement que le type de retour est Unité, le type est inféré par le compilateur.

fun hello (name: String) // compilera toujours print ("Hello $ name")

Fonctions sur une seule ligne

Les fonctions à une ligne ou à une ligne sont des fonctions qui ne sont que des expressions uniques. Dans cette fonction, nous nous débarrassons des accolades et utilisons le = symbole avant l'expression. En d'autres termes, nous nous débarrassons du bloc de fonction.

fun calCircumference (rayon: Double): Double retour (2 * Math.PI) * rayon

La fonction ci-dessus peut être raccourcie en une seule ligne:

fun calCircumference (rayon: Double) = (2 * Math.PI) * rayon

En regardant la fonction mise à jour ci-dessus, vous pouvez voir que notre code est plus concis en supprimant les accolades. , la revenir mot-clé, ainsi que le type de retour (qui est déduit par le compilateur). 

Vous pouvez toujours inclure le type de retour pour être plus explicite si vous voulez.

fun calCircumference (rayon: Double): Double = (2 * Math.PI) * rayon

Paramètres nommés

Les paramètres nommés permettent des fonctions plus lisibles en nommant les paramètres transmis à une fonction lorsqu’elle est appelée..

Dans l'exemple suivant, nous avons créé une fonction qui affiche mon nom complet..

fun sayMyFullName (firstName: String, lastName: String, middleName: String): Unit print ("Mon nom complet est $ firstName $ middleName $ lastName"); 

Pour exécuter la fonction ci-dessus, nous l'appellerions simplement ainsi:

sayMyFullName ("Chike", "Nnamdi", "Mgbemena")

En regardant l'appel de fonction ci-dessus, nous ne savons pas lequel Chaîne Les arguments de type correspondent aux paramètres de fonction (bien que certains IDE tels que IntelliJ IDEA puissent nous aider). Les utilisateurs de la fonction devront consulter la signature de la fonction (ou le code source) ou la documentation pour savoir à quoi correspond chaque paramètre..

sayMyFullName (firstName = "Chike", middleName = "Nnamdi", lastName = "Mgbemena")

Dans le deuxième appel de fonction ci-dessus, nous avons fourni les noms de paramètre avant les valeurs d'argument. Vous pouvez constater que cet appel de fonction est plus clair et lisible que le précédent. Cette façon d’appeler des fonctions permet de réduire les risques de bugs pouvant survenir lorsque des arguments du même type sont échangés par erreur..

L'appelant peut également modifier l'ordre des paramètres à l'aide de paramètres nommés. Par exemple:

sayMyFullName (lastName = "Mgbemena", middleName = "Nnamdi", firstName = "Chike") // sera toujours compilé

Dans le code ci-dessus, nous avons échangé la position d'argument de la Prénom avec le nom de famille. L'ordre des arguments n'a pas d'importance avec les paramètres nommés car le compilateur mappera chacun d'eux sur le paramètre de fonction approprié.

Paramètres par défaut

En Kotlin, nous pouvons donner à une fonction des valeurs par défaut pour n’importe lequel de ses paramètres. Ces valeurs par défaut sont utilisées si rien n'est attribué aux arguments lors de l'appel de la fonction. Pour faire cela en Java, il faudrait créer différentes méthodes surchargées.

Ici, dans notre calCircumference () méthode, nous avons modifié la méthode en ajoutant une valeur par défaut pour la pi paramètre-Math.PI, une constante de la java.lang.Math paquet. 

fun calCircumference (rayon: Double, pi: Double = Math.PI): Double = (2 * pi) * rayon

Lorsque nous appelons cette fonction, nous pouvons soit passer notre valeur approximative pour pi ou utilisez la valeur par défaut. 

print (calCircumference (24.0)) // a utilisé la valeur par défaut pour PI et imprime 150.79644737231007 print (calCircumference (24.0, 3.14)) // a passé la valeur pour PI et a imprimé 150.72

Voyons un autre exemple.

fun printName (firstName: String, middleName: String = "N / A", lastName: String) println ("prénom: $ prénom - deuxième prénom: $ deuxième prénom - $ nom de famille: $ dernier nom")

Dans le code suivant, nous avons essayé d'appeler la fonction, mais celle-ci ne sera pas compilée:

printName ("Chike", "Mgbemena") // ne compile pas

Dans l'appel de fonction ci-dessus, je passe mon nom et mon nom de famille à la fonction, dans l'espoir d'utiliser la valeur par défaut pour le deuxième prénom. Mais cela ne compilera pas car le compilateur est confus. Il ne sait pas ce que l'argument "Mgbemena" est pour-est-ce pour le deuxième nom ou la nom de famille paramètre? 

Pour résoudre ce problème, nous pouvons combiner des paramètres nommés et des paramètres par défaut. 

printName ("Chike", lastName = "Mgbemena") // va maintenant être compilé

Interopérabilité Java

Étant donné que Java ne prend pas en charge les valeurs de paramètre par défaut dans les méthodes, vous devez spécifier explicitement toutes les valeurs de paramètre lorsque vous appelez une fonction Kotlin à partir de Java. Mais Kotlin nous fournit les fonctionnalités nécessaires pour faciliter la tâche des appelants Java en annotant la fonction Kotlin avec @JvmOverloads. Cette annotation indiquera au compilateur Kotlin de générer les fonctions surchargées Java..

Dans l'exemple suivant, nous avons annoté la calCirumference () fonctionner avec @JvmOverloads.

@JvmOverloads fun calCircumference (rayon: Double, pi: Double = Math.PI): Double = (2 * pi) * rayon

Le code suivant a été généré par le compilateur Kotlin afin que les appelants Java puissent ensuite choisir lequel appeler.

// Java double calCircumference (double rayon, double pi); double calCirconférence (double rayon);

Dans la dernière définition de méthode Java générée, le pi paramètre a été omis. Cela signifie que la méthode utilisera la valeur par défaut pi valeur.

Arguments illimités

En Java, nous pouvons créer une méthode pour recevoir un nombre non spécifié d'arguments en incluant des points de suspension () après un type dans la liste des paramètres de la méthode. Ce concept est également soutenu par les fonctions Kotlin avec l’utilisation de la vararg modificateur suivi du nom du paramètre.

fun printInts (vararg ints: Int): Unit for (n in ints) print ("$ n \ t") printInts (1, 2, 3, 4, 5, 6) // imprimera 1 2 3 4 5 6

le vararg modificateur permet aux appelants de transmettre une liste d'arguments séparée par des virgules. En coulisse, cette liste d'arguments sera encapsulée dans un tableau.. 

Quand une fonction a plusieurs paramètres, le vararg paramètre est généralement le dernier. Il est également possible d'avoir des paramètres après la vararg, mais vous devrez utiliser des paramètres nommés pour les spécifier lorsque vous appelez la fonction. 

fun printNumbers (myDouble: Double, myFloat: Float, variable dans: Int) println (myDouble) println (myFloat) pour (n ints) print ("$ n \ t") printNumbers (1.34, 4.4F, 2, 3, 4, 5, 6) // compilera

Par exemple, dans le code ci-dessus, le paramètre avec le vararg modificateur est à la dernière position dans une liste de paramètres multiples (c’est ce que nous faisons habituellement). Mais que se passe-t-il si nous ne le voulons pas en dernière position? Dans l'exemple suivant, il est en deuxième position.

fun printNumbers (myDouble: Double, variables, Int, myFloat: Float) println (myDouble) println (myFloat) pour (n ints) print ("$ n \ t") printNumbers (1.34, 2, 3 , 4, 5, 6, myFloat = 4.4F) // compilera printNumbers (1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // ne compilera pas printNumbers (myDouble = 1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // ne compilera pas non plus

Comme vous pouvez le constater dans le code mis à jour ci-dessus, nous avons utilisé des arguments nommés sur le dernier paramètre pour résoudre ce problème..

Épandeur

Disons que nous voulons passer un tableau d'entiers à notre printNumbers () une fonction. La fonction s'attend toutefois à ce que les valeurs soient déroulées dans une liste de paramètres. Si vous essayez de passer le tableau directement dans printNumbers (), vous verrez qu'il ne compilera pas. 

val intsArray: IntArray = intArrayOf (1, 3, 4, 5) printNumbers (1.34, intsArray, myFloat = 4.4F) // ne sera pas compilé

Pour résoudre ce problème, nous devons utiliser l'opérateur spread *. Cet opérateur décompactera le tableau puis transmettra les éléments individuels comme arguments dans la fonction pour nous.. 

val intsArray: IntArray = intArrayOf (1, 3, 4, 5) printNumbers (1.34, * intsArray, myFloat = 4.4F) // va maintenant être compilé

En insérant l'opérateur de propagation * en face de intsArray dans la liste des arguments de la fonction, le code compile maintenant et produit le même résultat que si nous avions passé les éléments de intsArray sous forme de liste d'arguments séparés par des virgules. 

Renvoyer plusieurs valeurs

Parfois, nous voulons renvoyer plusieurs valeurs d'une fonction. Une façon consiste à utiliser le Paire tapez Kotlin pour créer un Paire et ensuite le retourner. Ce Paire La structure contient deux valeurs accessibles ultérieurement. Ce type Kotlin peut accepter tous les types que vous fournissez à son constructeur. Et en plus, les deux types n'ont même pas besoin d'être identiques. 

getUserNameAndState (id: Int) amusant: paire require (id> 0, "Erreur: id est inférieur à 0") val userNames: Map = mapOf (101 à "Chike", 102 à "Segun", 104 à "Jane") val utilisateurs: Carte = mapOf (101 à "Lagos", 102 à "Imo", 104 à "Enugu") val userName = userNames [id] val userState = userStates [id] return Pair (userName, userState)

Dans la fonction ci-dessus, nous avons construit un nouveau Paire en passant le Nom d'utilisateur et état utilisateur variables en tant que premier et second arguments respectivement à son constructeur, puis renvoyé cette Paire à l'appelant.

Une autre chose à noter est que nous avons utilisé une fonction appelée exiger() dans le getUserNameAndState () une fonction. Cette fonction d’aide de la bibliothèque standard sert à donner à nos appelants de fonction une condition préalable à remplir, sinon une Exception d'argument illégal sera jeté (nous discuterons des exceptions dans Kotlin dans un prochain post). Le deuxième argument optionnel à exiger() est une fonction littérale renvoyant un message à afficher si l'exception est levée. Par exemple, en appelant le getUserNameAndState () fonction et passage -1 comme argument, cela déclenchera:

 

Récupération des données de Paire

val userNameAndStatePair: Pair = getUserNameAndState (101) println (nom d'utilisateurAndStatePair.first) // Chike println (nom d'utilisateurAndStatePair.second) // Lagos

Dans le code ci-dessus, nous avons accédé aux première et deuxième valeurs de la Paire tapez en utilisant son premier et seconde Propriétés.

Cependant, il existe un meilleur moyen de le faire: la déstructuration.

val (nom, état) = getUserNameAndState (101) println (nom) // Chike println (état) // Lagos

Ce que nous avons fait dans le code mis à jour ci-dessus est d’affecter directement les première et deuxième valeurs des valeurs renvoyées. Paire taper aux variables prénom et Etat respectivement. Cette fonctionnalité s'appelle déclaration de déstructuration.

Valeurs triple retour et au-delà

Maintenant, si vous voulez renvoyer trois valeurs à la fois? Kotlin nous fournit un autre type utile appelé Tripler.

fun getUserNameStateAndAge (id: Int): Triple require (id> 0, "l'id est inférieur à 0") val userNames: Map = mapOf (101 à "Chike", 102 à "Segun", 104 à "Jane") val utilisateurs: Carte = mapOf (101 à "Lagos", 102 à "Imo", 104 à "Enugu") val userName = userNames [id] val userState = userStates [id] val userAge = 6 renvoie Triple (userNames [id], userStates [id ], userAge) val (nom, état, âge) = getUserNameStateAndAge (101) println (nom) // Chike println (état) // Lagos println (age) // 6

Je suis sûr que certains d'entre vous se demandent quoi faire si vous voulez renvoyer plus de trois valeurs. La réponse à cela sera dans un post ultérieur, quand nous discuterons des classes de données de Kotlin.

Conclusion

Dans ce tutoriel, vous avez découvert les packages et les fonctions de base du langage de programmation Kotlin. Dans le prochain didacticiel de la série Kotlin From Scratch, vous en apprendrez plus sur les fonctions de Kotlin. À bientôt!

Pour en savoir plus sur la langue Kotlin, je vous recommande de consulter la documentation Kotlin. Ou consultez certains de nos autres articles sur le développement d'applications Android ici sur Envato Tuts+!