Zoeken…


Syntaxis

  • leuke naam ( params ) = ...
  • leuke naam ( params ) {...}
  • leuke naam ( params ): type {...}
  • leuk < Type Argument > Naam ( Params ): Type {...}
  • inline fun Naam ( Params ): Type {...}
  • { ArgName : ArgType -> ...}
  • { ArgName -> ...}
  • { ArgNames -> ...}
  • {( ArgName : ArgType ): Type -> ...}

parameters

Parameter Details
Naam Naam van de functie
params Waarden die aan de functie worden gegeven met een naam en type: Name : Type
Type Retourneer het type van de functie
Typ Argument Type parameter gebruikt in generieke programmering (niet noodzakelijkerwijs retourtype)
ArgName Naam van de waarde die aan de functie is gegeven
ArgType Typ specifier voor ArgName
ArgNames Lijst met ArgName gescheiden door komma's

Functies Andere functies gebruiken

Zoals te zien is in "Lambda-functies", kunnen functies andere functies als parameter nemen. Het "functietype" dat u nodig hebt om functies aan te geven die andere functies aannemen, is als volgt:

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

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

U kunt bijvoorbeeld het vaagste type, () -> Any? , om een functie aan te geven die tweemaal een lambdafunctie uitvoert:

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

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

Lambda-functies

Lambda-functies zijn anonieme functies die meestal worden gemaakt tijdens een functie-aanroep om als functieparameter te fungeren. Ze worden verklaard door omringende uitdrukkingen met {accolades} - als er argumenten nodig zijn, worden deze voor een pijl geplaatst -> .

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

Het laatste statement binnen een lambda-functie is automatisch de retourwaarde.

De typen zijn optioneel, als u de lambda op een plaats zet waar de compiler de typen kan afleiden.

Meerdere argumenten:

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

Als de lambda-functie hoeft slechts één argument, dan is de lijst met argumenten kan worden weggelaten en de enkel argument worden verwezen naar het gebruik van it plaats.

{ "Your name is $it" }

Als het enige argument voor een functie een lambdafunctie is, kunnen haakjes volledig worden weggelaten uit de functieaanroep.

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

Functie referenties

We kunnen een functie verwijzen zonder daadwerkelijk noemde het door voor de naam van de functie met :: . Dit kan vervolgens worden doorgegeven aan een functie die een andere functie als parameter accepteert.

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

Functies zonder ontvanger worden geconverteerd naar (ParamTypeA, ParamTypeB, ...) -> ReturnType ParamTypeA waarbij ParamTypeA , ParamTypeB ... het type functieparameters zijn en `ReturnType1 het type functie-retourwaarde is.

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

Functies met een ontvanger (zij het een uitbreidingsfunctie of een lidfunctie) hebben een andere syntaxis. U moet de typenaam van de ontvanger toevoegen vóór de dubbele punt:

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.

Wanneer de ontvanger van een functie een object is, wordt de ontvanger weggelaten uit de parameterlijst, omdat deze slechts één exemplaar van een dergelijk type is.

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.

Sinds kotlin 1.1 kan functiereferentie ook worden begrensd door een variabele, die dan een begrensde functiereferentie wordt genoemd .

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

Merk op dat dit voorbeeld alleen wordt gegeven om te laten zien hoe begrensde functie-referentie werkt. Het is een slechte gewoonte in alle andere zintuigen.

Er is echter een speciaal geval. Een extensiefunctie die als lid is aangegeven, kan niet worden gebruikt.

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

Basisfuncties

Functies worden gedeclareerd met het fun trefwoord, gevolgd door een functienaam en eventuele parameters. U kunt ook het retourtype van een functie opgeven, die standaard wordt ingesteld op Unit . De hoofdtekst van de functie staat tussen accolades {} . Als het retourtype anders is dan Unit , moet de instantie een retourverklaring afgeven voor elke afsluitende vertakking binnen de instantie.

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

Een korte versie van hetzelfde:

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

En het type kan worden weggelaten omdat het kan worden afgeleid:

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

Steno functies

Als een functie slechts één uitdrukking bevat, kunnen we de accolades weglaten en in plaats daarvan een gelijken gebruiken, zoals een variabele toewijzing. Het resultaat van de uitdrukking wordt automatisch geretourneerd.

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

Inline functies

Functies kunnen inline worden gedeclareerd met het inline voorvoegsel, en in dit geval werken ze als macro's in C - in plaats van te worden aangeroepen, worden ze tijdens het compileren vervangen door de bodycode van de functie. Dit kan onder sommige omstandigheden leiden tot prestatievoordelen, vooral wanneer lambdas als functieparameters wordt gebruikt.

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

Een verschil met C-macro's is dat inline-functies geen toegang hebben tot het bereik van waaruit ze worden genoemd:

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

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

Operator functies

Kotlin stelt ons in staat om implementaties te bieden voor een vooraf gedefinieerde set operators met vaste symbolische weergave (zoals + of * ) en vaste prioriteit. Om een operator te implementeren, bieden we een ledenfunctie of een uitbreidingsfunctie met een vaste naam, voor het overeenkomstige type. Functies die operators overbelasten, moeten worden gemarkeerd met de 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

Meer operatorfuncties zijn hier te vinden



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow