サーチ…
構文
- 楽しい名前 ( Params )= ...
- 楽しい名前 ( Params ){...}
- 楽しい名前 ( Params ): タイプ {...}
- fun < タイプ引数 > 名前 ( Params ): タイプ {...}
- inline fun 名前 ( Params ): タイプ {...}
- { ArgName : ArgType - > ...}
- { ArgName - > ...}
- { ArgNames - > ...}
- {( ArgName : ArgType ): 型 - > ...}
パラメーター
パラメータ | 詳細 |
---|---|
名 | 関数の名前 |
Params | 関数に与えられた名前と型の値: Name : Type |
タイプ | 関数の戻り値の型 |
型引数 | ジェネリックプログラミングで使用される型パラメータ(必ずしも型を返す必要はない) |
ArgName | 関数に与えられた値の名前 |
ArgType | ArgNameの型指定子 |
ArgNames | コンマで区切られたArgNameのリスト |
他の関数を取る関数
「ラムダ関数」に見られるように、関数は他の関数をパラメータとして取ることができます。他の機能を持つ関数を宣言するために必要な "関数型"は次のとおりです:
# Takes no parameters and returns anything
() -> Any?
# Takes a string and an integer and returns ReturnType
(arg1: String, arg2: Int) -> ReturnType
たとえば、曖昧な型の() -> Any?
使用できます() -> Any?
ラムダ関数を2回実行する関数を宣言する:
fun twice(x: () -> Any?) {
x(); x();
}
fun main() {
twice {
println("Foo")
} # => Foo
# => Foo
}
ラムダ関数
ラムダ関数は、通常、関数呼び出しの際に関数パラメータとして動作するように作成される匿名関数です。引数が必要な場合、これらは矢印の前に置かれ-彼らは{中括弧}で式を囲むことで宣言されています->
。
{ name: String ->
"Your name is $name" //This is returned
}
ラムダ関数の中の最後のステートメントは自動的に戻り値です。
コンパイラが型を推論できる場所にラムダを置くと、型はオプションです。
複数の引数:
{ argumentOne:String, argumentTwo:String ->
"$argumentOne - $argumentTwo"
}
ラムダ関数が1つの引数しか必要としない場合は、引数リストを省略しit
代わりに1つの引数を参照することができます。
{ "Your name is $it" }
関数への唯一の引数がラムダ関数である場合、関数呼び出しからかっこを完全に省略することができます。
# These are identical
listOf(1, 2, 3, 4).map { it + 2 }
listOf(1, 2, 3, 4).map({ it + 2 })
関数参照
関数の名前の前に::
付けることで、関数を実際に呼び出さずに関数を参照することができます。これは、他の関数をパラメータとして受け入れる関数に渡すことができます。
fun addTwo(x: Int) = x + 2
listOf(1, 2, 3, 4).map(::addTwo) # => [3, 4, 5, 6]
受信せずに機能をに変換されます(ParamTypeA, ParamTypeB, ...) -> ReturnType
ParamTypeA
、 ParamTypeB
... ReturnType1は関数の戻り値のタイプである`関数パラメータのタイプであり、。
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
レシーバ(拡張機能であろうとメンバ関数であろうと)を持つ関数は、異なった構文を持っています。ダブルコロンの前にレシーバのタイプ名を追加する必要があります:
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.
しかし、関数の受信者がオブジェクトである場合、受信者はそのような型のインスタンスの1つだけであるため、パラメータリストから省略されます。
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.
kotlin 1.1以降、関数リファレンスは変数にバインドすることもできます。これは、バウンド関数リファレンスと呼ばれます 。
fun makeList(last: String?): List<String> {
val list = mutableListOf("a", "b", "c")
last?.let(list::add)
return list
}
この例は、有界関数参照がどのように機能するかを示すためにのみ与えられていることに注意してください。他のすべての感覚では悪い習慣です。
しかし、特殊なケースがあります。メンバとして宣言された拡張関数は参照できません。
class Foo
class Bar {
fun Foo.foo() {}
val ref = Foo::foo // compile error
}
基本機能
関数はfun
キーワードを使用して宣言され、その後に関数名とパラメータが続きます。関数の戻り値の型を指定することもできます。既定値はUnit
です。関数の本体は中括弧{}
囲まれています。戻り値の型がUnit
以外の場合、本体は、本体内のすべての終了ブランチに対してreturn文を発行する必要があります。
fun sayMyName(name: String): String {
return "Your name is $name"
}
同じものの簡略版:
fun sayMyName(name: String): String = "Your name is $name"
また、型は推論できるので省略することができます:
fun sayMyName(name: String) = "Your name is $name"
簡略関数
関数に式が1つだけ含まれている場合は、変数代入のように、中括弧を省略して代わりにequalsを使用できます。式の結果は自動的に返されます。
fun sayMyName(name: String): String = "Your name is $name"
インライン関数
関数は、 inline
接頭辞を使用してinline
で宣言することができます。この場合、呼び出されるのではなく、Cのマクロのように動作します。コンパイル時に関数の本体コードに置き換えられます。これは、主にラムダが機能パラメータとして使用される場合に、パフォーマンス上の利点をもたらすことがあります。
inline fun sayMyName(name: String) = "Your name is $name"
Cマクロとの違いの1つは、インライン関数が呼び出されたスコープにインライン関数がアクセスできないことです。
inline fun sayMyName() = "Your name is $name"
fun main() {
val name = "Foo"
sayMyName() # => Unresolved reference: name
}
演算子関数
Kotlinは固定記号表現( +
や*
)と固定優先順位を持つ定義済みの演算子のセットを実装することを可能にします。演算子を実装するために、対応する型の固定名を持つメンバ関数または拡張関数を提供します。オーバーロードするoperator
子にoperator
修飾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
より多くの演算子関数がここにあります