Recherche…


Syntaxe

  • fun Nom ( Params ) = ...
  • Nom fun ( Params ) {...}
  • fun Nom ( Params ): Type {...}
  • fun < Type Argument > Name ( Params ): Type {...}
  • inline fun Name ( Params ): tapez {...}
  • { ArgName : ArgType -> ...}
  • { ArgName -> ...}
  • { ArgNames -> ...}
  • {( ArgName : ArgType ): Type -> ...}

Paramètres

Paramètre Détails
prénom Nom de la fonction
Params Valeurs données à la fonction avec un nom et un type: Name : Type
Type Type de retour de la fonction
Type Argument Paramètre de type utilisé dans la programmation générique (pas nécessairement le type de retour)
ArgName Nom de la valeur donnée à la fonction
ArgType Spécificateur de type pour ArgName
ArgNames Liste de ArgName séparés par des virgules

Fonctions prenant d'autres fonctions

Comme on le voit dans "Fonctions Lambda", les fonctions peuvent prendre d'autres fonctions en paramètre. Le "type de fonction" dont vous aurez besoin pour déclarer des fonctions prenant d'autres fonctions est le suivant:

# Takes no parameters and returns anything
() -> Any?

# Takes a string and an integer and returns ReturnType
(arg1: String, arg2: Int) -> ReturnType

Par exemple, vous pouvez utiliser le type le plus vague, () -> Any? , pour déclarer une fonction qui exécute une fonction lambda deux fois:

fun twice(x: () -> Any?) {
    x(); x();
}

fun main() {
    twice {
        println("Foo")
    } # => Foo
      # => Foo
}

Fonctions Lambda

Les fonctions Lambda sont des fonctions anonymes qui sont généralement créées lors d'un appel de fonction pour agir en tant que paramètre de fonction. Ils sont déclarés par des expressions environnantes avec {accolades} - si des arguments sont nécessaires, ils sont mis avant une flèche -> .

{ name: String ->
    "Your name is $name" //This is returned
}

La dernière instruction dans une fonction lambda est automatiquement la valeur de retour.

Les types sont optionnels, si vous placez le lambda sur un emplacement où le compilateur peut en déduire les types.

Plusieurs arguments:

{ argumentOne:String, argumentTwo:String ->
    "$argumentOne - $argumentTwo"
}

Si la fonction lambda ne nécessite qu'un seul argument, la liste des arguments peut être omise et l'argument unique peut être utilisé it place.

{ "Your name is $it" }

Si le seul argument d'une fonction est une fonction lambda, les parenthèses peuvent être complètement omises de l'appel de fonction.

# These are identical
listOf(1, 2, 3, 4).map { it + 2 }
listOf(1, 2, 3, 4).map({ it + 2 })

Références de fonction

Nous pouvons référencer une fonction sans l'appeler en préfixant le nom de la fonction avec :: . Cela peut ensuite être passé à une fonction qui accepte une autre fonction en tant que paramètre.

fun addTwo(x: Int) = x + 2
listOf(1, 2, 3, 4).map(::addTwo) # => [3, 4, 5, 6]

Les fonctions sans récepteur seront converties en (ParamTypeA, ParamTypeB, ...) -> ReturnTypeParamTypeA , ParamTypeB ... sont le type des paramètres de la fonction et `ReturnType1 est le type de la valeur de retour de la fonction.

fun foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
    //...
}
println(::foo::class.java.genericInterfaces[0]) 
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar

Fonctions avec un récepteur (que ce soit une fonction d'extension ou une fonction membre) a une syntaxe différente. Vous devez ajouter le nom de type du récepteur avant les deux points suivants:

class Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
    //...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0]) 
// kotlin.jvm.functions.Function4<Foo, Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo, Foo0, Foo1, Foo2) -> Bar
// takes 4 parameters, with receiver as first and actual parameters following, in their order

// this function can't be called like an extension function, though
val ref = Foo::foo
Foo().ref(Foo0(), Foo1(), Foo2()) // compile error

class Bar {
    fun bar()
}
print(Bar::bar) // works on member functions, too.

Cependant, lorsque le récepteur d'une fonction est un objet, le récepteur est omis de la liste de paramètres, car il s'agit et n'est qu'une instance de ce type.

object Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
    //...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0]) 
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar
// takes 3 parameters, receiver not needed

object Bar {
    fun bar()
}
print(Bar::bar) // works on member functions, too.

Depuis kotlin 1.1, la référence de fonction peut également être liée à une variable, appelée alors référence de fonction bornée .

1.1.0
fun makeList(last: String?): List<String> {
    val list = mutableListOf("a", "b", "c")
    last?.let(list::add)
    return list
}

Notez que cet exemple est donné uniquement pour montrer comment fonctionne la référence de fonction bornée. C'est une mauvaise pratique dans tous les autres sens.

Il y a cependant un cas particulier. Une fonction d'extension déclarée en tant que membre ne peut pas être référencée.

class Foo
class Bar {
    fun Foo.foo() {}
    val ref = Foo::foo // compile error
}

Les fonctions de base

Les fonctions sont déclarées à l'aide du mot-clé fun , suivi d'un nom de fonction et de tous les paramètres. Vous pouvez également spécifier le type de retour d'une fonction, par défaut Unit . Le corps de la fonction est entre accolades {} . Si le type de retour est autre que Unit , le corps doit émettre une déclaration de retour pour chaque branche de terminaison dans le corps.

fun sayMyName(name: String): String {
    return "Your name is $name" 
} 

Une version abrégée du même:

fun sayMyName(name: String): String = "Your name is $name" 

Et le type peut être omis car il peut être déduit:

fun sayMyName(name: String) = "Your name is $name" 

Fonctions abrégées

Si une fonction ne contient qu'une seule expression, nous pouvons omettre les accolades et utiliser plutôt une équation comme une affectation de variable. Le résultat de l'expression est renvoyé automatiquement.

fun sayMyName(name: String): String = "Your name is $name" 

Fonctions en ligne

Les fonctions peuvent être déclarées en ligne en utilisant le préfixe inline , et dans ce cas elles agissent comme des macros dans C - plutôt que d'être appelées, elles sont remplacées par le code du corps de la fonction au moment de la compilation. Cela peut entraîner des avantages en termes de performances dans certaines circonstances, principalement lorsque les lambdas sont utilisés comme paramètres de fonction.

inline fun sayMyName(name: String) = "Your name is $name" 

Une différence avec les macros C est que les fonctions en ligne ne peuvent pas accéder à la portée à partir de laquelle elles sont appelées:

inline fun sayMyName() = "Your name is $name"

fun main() {
    val name = "Foo"
    sayMyName() # => Unresolved reference: name
}

Fonctions opérateur

Kotlin nous permet de fournir des implémentations pour un ensemble prédéfini d'opérateurs avec une représentation symbolique fixe (comme + ou * ) et une priorité fixe. Pour implémenter un opérateur, nous fournissons une fonction membre ou une fonction d'extension avec un nom fixe, pour le type correspondant. Les fonctions qui surchargent les opérateurs doivent être marquées avec le modificateur d' operator :

data class IntListWrapper (val wrapped: List<Int>) {
    operator fun get(position: Int): Int = wrapped[position]
}

val a = IntListWrapper(listOf(1, 2, 3))
a[1] // == 2

Vous trouverez plus de fonctions opérateur ici



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow