Szukaj…


Składnia

  • fun Name ( Params ) = ...
  • fun Name ( Params ) {...}
  • fun Name ( Params ): Wpisz {...}
  • fun < Type Argument > Name ( Params ): Type {...}
  • inline zabawa nazwisko (Params): Typ {...}
  • { ArgName : ArgType -> ...}
  • { ArgName -> ...}
  • { ArgNames -> ...}
  • {( ArgName : ArgType ): Type -> ...}

Parametry

Parametr Detale
Nazwa Nazwa funkcji
Params Wartości nadane funkcji o nazwie i typie: Name : Type
Rodzaj Zwraca typ funkcji
Wpisz Argument Parametr typu używany w programowaniu ogólnym (niekoniecznie typ zwracany)
ArgName Nazwa wartości nadana funkcji
ArgType Wpisz specyfikator dla ArgName
ArgNames Lista ArgName oddzielona przecinkami

Funkcje Przyjmowanie innych funkcji

Jak widać w „Funkcjach Lambda”, funkcje mogą przyjmować inne funkcje jako parametry. „Typ funkcji”, który będzie potrzebny do zadeklarowania funkcji, które przyjmują inne funkcje, jest następujący:

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

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

Na przykład możesz użyć najbardziej niejasnego typu, () -> Any? , aby zadeklarować funkcję, która wykonuje funkcję lambda dwukrotnie:

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

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

Funkcje Lambda

Funkcje Lambda są funkcjami anonimowymi, które są zwykle tworzone podczas wywołania funkcji i działają jako parametr funkcji. Są deklarowane przez otaczające wyrażenia za pomocą {nawiasów klamrowych} - jeśli potrzebne są argumenty, są one umieszczane przed strzałką -> .

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

Ostatnia instrukcja w funkcji lambda jest automatycznie wartością zwracaną.

Typy są opcjonalne, jeśli umieścisz lambda w miejscu, w którym kompilator może wnioskować o typach.

Wiele argumentów:

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

Jeśli tylko funkcja lambda wymaga jednego argumentu, lista argument może być pominięte, a pojedynczy argument być określane przy użyciu it zamiast.

{ "Your name is $it" }

Jeśli jedynym argumentem funkcji jest funkcja lambda, wówczas nawiasy można całkowicie pominąć w wywołaniu funkcji.

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

Referencje funkcji

Możemy odwoływać się do funkcji bez wywoływania jej, poprzedzając nazwę funkcji znakiem :: . Można to następnie przekazać do funkcji, która przyjmuje jako parametr inną funkcję.

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

Funkcje bez odbiornika zostaną przekonwertowane na (ParamTypeA, ParamTypeB, ...) -> ReturnType gdzie ParamTypeA , ParamTypeB ... są typem parametrów funkcji, a `ReturnType1 jest typem zwracanej wartości funkcji.

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

Funkcje z odbiornikiem (funkcją rozszerzającą lub funkcją składową) mają inną składnię. Musisz dodać nazwę typu odbiornika przed dwukropkiem:

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.

Jednak gdy odbiornik funkcji jest obiektem, odbiornik jest pomijany na liście parametrów, ponieważ jest to i jest tylko jedna instancja tego typu.

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.

Od Kotlin 1,1 odniesienia funkcja może być ograniczona do zmiennej, która jest następnie nazywana ograniczonym odniesienia funkcję.

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

Uwaga: ten przykład podano jedynie w celu pokazania, jak działa odwołanie do funkcji ograniczonej. To zła praktyka we wszystkich innych zmysłach.

Jest jednak szczególny przypadek. Nie można odwoływać się do funkcji rozszerzenia zadeklarowanej jako członek.

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

Podstawowe funkcje

Funkcje deklarowane są za pomocą słowa kluczowego fun , po którym następuje nazwa funkcji i dowolne parametry. Możesz także określić typ zwracany przez funkcję, która domyślnie ma wartość Unit . Ciało funkcji jest zamknięte w nawiasach klamrowych {} . Jeśli typ zwracany jest inny niż Unit , treść musi wystawić instrukcję return dla każdej końcowej gałęzi w treści.

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

Skrócona wersja tego samego:

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

Typ można pominąć, ponieważ można go wywnioskować:

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

Funkcje skrótowe

Jeśli funkcja zawiera tylko jedno wyrażenie, możemy pominąć nawiasy klamrowe i zamiast tego użyć znaku równości, np. Przypisania zmiennej. Wynik wyrażenia jest zwracany automatycznie.

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

Funkcje wbudowane

Funkcje mogą być deklarowane inline za pomocą przedrostka inline , w tym przypadku działają one jak makra w C - zamiast być wywoływane, są zastępowane kodem funkcji w czasie kompilacji. Może to prowadzić do poprawy wydajności w niektórych okolicznościach, głównie tam, gdzie lambda są używane jako parametry funkcji.

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

Jedną różnicą w stosunku do makr C jest to, że funkcje wbudowane nie mogą uzyskać dostępu do zakresu, z którego są nazywane:

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

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

Funkcje operatora

Kotlin pozwala nam zapewnić implementacje dla predefiniowanego zestawu operatorów o stałej reprezentacji symbolicznej (jak + lub * ) i ustalonym priorytecie. Aby zaimplementować operator, zapewniamy funkcję członka lub funkcję rozszerzenia o stałej nazwie dla odpowiedniego typu. Funkcje przeciążające operatorów należy oznaczyć modyfikatorem 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

Więcej funkcji operatora można znaleźć tutaj



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow