関数では、特定の機能のコード ブロックを定義できます。
1. 関数の定義
Kotlin 言語定義関数の基本形式は次のとおりです。
fun 関数名 ([パラメータ: パラメータの型, パラメータ: パラメータの型...]) [:戻り値の型] { //関数本体}
関数本体の戻り値が 1 つだけの場合は、次の形式に簡略化できます。
fun 関数名 ([パラメータ: パラメータの型, パラメータ: パラメータの型...]) [: 戻り値の型] = 式
上記の [ ] はオプションのオプションを示しており、無視できます。
例: 加算を実行する関数を定義するには、次のように定義できます。
fun add(x:Int,y:Int){
return x+y
}
または
fun add(x:Int,y:Int) = x+y
2. 特別な機能
1.拡張機能
Kotlin は、クラスを継承したり、デコレーター パターンなどのデザイン パターンを使用したりすることなく、拡張関数を通じて既存のクラスに新しい機能を提供します。定義は次のとおりです。
fun クラス名.関数名 ([パラメータ 1, パラメータ 2, ....]): 戻り値の型 {
// メソッド本体
}
たとえば、次のように定義された新しい関数 display を String クラスに追加します。
fun String.display(){
println(this)
}
次に、次のコード ブロックを呼び出します。
"hello".display()
実行結果は次のようになります:
こんにちは
2.高階関数
Kotlin は、関数のパラメーター (ラムダ式としても表現可能) または関数としての戻り値 (ラムダ式) をサポートしています。このような形式の関数は高階関数と呼ばれます 2.1 関数のパラメーターとしての関数
例
:
fun operate(x:Double,y:Double,operator:(Double,Double)->Any):Any = operator(x,y)
上記のコードでは、関数のパラメータ演算子が定義されており、演算子の演算結果が関数の戻り値として返されます。
上記の関数を呼び出します。
val method = {
x:Double,y:Double->
x+y
}
val result = operate(20.0,30.0,method)
または
val result=operate(20.0,30.0,operator= {
x:Double,y:Double->
x+y
})
または
val result = operate(20.0,30.0) {
x, y ->
x + y
}
2.2 関数の戻り値としての関数
fun operate(expression:String):(Double,Double)->Any {
val op = when{
expression.contains("+")->::add
expression.contains("-")->::sub
expression.contains("x")->::mul
expression.contains("/")->::div
expression.contains("%")->::mod
expression.contains(">")->::isBigger
else->throw ArithmeticException("$expression 出现错误!")
}
return op
}
このうち、add、sub、mul、div などはすべて定義された関数です。次のようなフォーム
fun add(x:Double,y:Double) = x+y
fun sub(x:Double,y:Double) = x-y
fun mul(x:Double,y:Double) = x*y
fun div(x:Double,y:Double) = x/y
fun mod(x:Double,y:Double) = x%y
fun isBigger(x:Double,y:Double) = x>y
3. インライン関数
インライン関数 (インライン関数またはコンパイル時拡張関数とも呼ばれます) は、特定の関数のインライン展開 (インライン展開とも呼ばれます) を実行するようにコンパイラーにアドバイスするプログラミング言語の構造です。Kotlin 言語では、関数がインラインとしてマークされると、関数のメソッド本体内のすべてのコードが、メソッド間のスタックにプッシュされるのではなく、呼び出される場所に移動されます。コンパイル時に、この関数が呼び出された場所がこの関数のメソッド本体に置き換えられます。
inline fun show(message:String){
println(message)
}
fun main(){
println("main测试内联函数")
show("内联函数")
println("测试结束")
}
Android Studio で Tools/Kotlin/Show Kotlin Bytecodes を選択すると、表示される結果は次のとおりです。
「逆コンパイル」ボタンをクリックすると、逆コンパイルされたコードが表示されます。
インラインはラムダ式でよく使用され、パフォーマンスを向上させることができます。
inline fun operateArithmetic(op:String):(Double,Double)->Any{
return when(op){
"+"->::add
"-"->::sub
"x"->::mul
"/"->::div
"%"->::mod
">"->::isBigger
else-> throw ArithmeticException("运算错误!")
}
}
fun main(){
println("main测试内联函数")
val op = operateArithmetic("+")
println(op(23.34,45.034))
println("测试结束")
}
3. 標準機能
1.let 関数
let 関数は、オブジェクトのコンテキストでコード ブロックを実行し、コードの実行をより簡潔にします
。
@InlineOnly
public inline fun <T, R> T.let (ブロック: (T) -> R):R
例:
fun main(){
val message:String? = "hello kotlin world"
//let将当前对象message执行多次操作
val c = message?.let {
it:String->
println(it.length)
println(it.lines())
"something"
}
println(message)
println(c)
}
実行結果は次のようになります:
18
[hello kotlin world]
hello kotlin world
何か
上記のコードでは、「何か」が削除された場合、let 関数の呼び出しには戻り値がありません。
2.with関数
with関数は、指定されたレシーバをレシーバとして、指定されたファンクションブロックを呼び出し、その結果を返す、オブジェクトに関連するメソッドを複数回連続して呼び出す処理です。
定義の基本形式:
@InlineOnly
public inline fun <T, R> with(
レシーバー: T,
ブロック: T. () -> R
): R
例:
fun main(){
var message="hello kotlin world"
val c=with(message){
println(length)
println(lines())
"$this welcome to new world"
}//返回最后一行的结果
println(message)
println(c)
}
実行結果は次のようになります:
18
[hello kotlin world]
hello kotlin world
hello kotlin world 新しい世界へようこそ
3. run 関数
run 関数は、これをレシーバーとして使用して、現在のオブジェクトにアクセスし、オブジェクトに対して複数の異なる呼び出しを実行し、結果を返します。ラムダ式をパラメータとして受け取ります。現在のオブジェクトは、Lambda 式のコンテキストとして機能します。run 関数を呼び出すと、戻り値は Lambda 関数ブロックの最後の行になるか、戻り値の式を指定します。これを使用して、
関数ブロック定義の基本形式にアクセスします。
@InlineOnly
public inline fun <T, R> T.run (ブロック: T.() -> R): R
例:
fun main(){
var message = "hello kotlin world"
val c =message.run{
println(this.length)
println(this.lines())
"$this welcome to new world"
}//返回最后一行的结果
println(message)
println(c)
}
4.apply 関数
apply 関数の主な機能は、オブジェクトの初期化関数を簡素化することです。apply 関数は Lambda 式を受け入れ、Lambda 式のコンテキストはオブジェクト自体です。apply 関数の戻り値はオブジェクトそのものです。
定義の基本形式:
@InlineOnly
public inline fun T.apply (ブロック: T.() -> ユニット): T
例:
fun main(){
var message:String? = "hello kotlin world"
val c = message?.apply{
println(length)
lines()+" welcome "
}//返回this对象
println(c)
println(message)
}
実行結果は次のようになります: *
18
hello kotlin world
hello kotlin world *
5. also 関数
also 関数は、let 関数のあらゆるシナリオに適しており、一般に複数の拡張関数のチェーン呼び出しに使用できます。also 関数は let 関数に似ており、独自の特徴があります。一方で、 also 関数は現在のオブジェクトを Lambda 式のコンテキストとして使用し、他方では、 also 関数の戻り値は渡された現在のオブジェクト。
定義の基本形式:
@InlineOnly
@SinceKotlin
public inline fun T. also (ブロック: (T) -> ユニット): T
例:
fun main(){
var message:String? = "hello kotlin world"
val c = message?.also{
println(it.length)
it.lines()+" welcome "
}//返回this对象
println(c)
println(message)
}
実行結果は次のようになります。
18
hello kotlin world
hello kotlin world
参考文献
チェン・イー『Android モバイル アプリケーション開発 (マイクロコース版)』清華大学出版局 ISBN 978-7-302-59734-6