Kotlin/関数

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

関数[編集]

グローバル変数[編集]

コード冒頭にある、どこの関数の中でもない冒頭の場所を「グローバル領域」という。

そのグローバル領域で、変数を宣言する事が出来る。グローバル変数は、main関数など個別の関数で再宣言しないで、その変数を呼び出せる。

コード例
//グローバル領域はここ
var i : Int = 20    // これがグローバル変数

// ↑ここまでグローバル領域

// 以降、もはやグローバル領域ではない
fun main() {    
    println(i)
}
実行結果
20

ユーザ定義関数[編集]

関数(function)とは、処理をまとめたものである。プログラマーが関数を自作する事もでき、そのような関数を「ユーザ定義関数」と言う。

いっぽう、「println」のように、元から用意されている関数のことを「組み込み関数」(ビルトイン関数)と言ったり「標準関数」と言ったり、色々な言い方がある。


さて、ユーザ定義関数の書式は、

fun 関数名(引数名: 引数の型) : 戻り値の型 {
    return 戻り値
}

である。

Kotlinにおけるユーザ定義関数の例を示す。下記の「test」がユーザ定義関数である。

コード例
fun test(i: Int) : Int {
    return i + 5
}

fun main() {
    var i : Int 
    i =10
        
    println(test(i))
}


実行結果
15

ユーザ定義関数の中で変数を使う場合は、グローバル変数でない限りは、必ずそのユーザ定義関数で再宣言する必要があります(しないとコンパイル時にエラー)。


Kotlinのユーザ定義変数内では、グローバル変数を使える。グローバル変数を宣言すると、その変数をどのユーザ定義関数からでも、書き換えしやすくなります。一方で、バグによる意図しない書き換えを防ぎたい場合には、あえてグローバル変数を用いない方法も可能です。

下記コードに、グローバル変数を用いる例を示します。

コード例
var i : Int = 30 

fun add()  {
    i = i + 5
}

fun main() {
    add()    
        
    println(i)
}


実行結果
35


なお、関数の引数は、必要が無ければ省略できる。戻り値の型も、そもそも戻り値が無い場合には型を省略できる。

戻り値の無い場合にそのことを明示したい場合、Unit という型名を使う。(Unit は、Java でいう void に相当。)


引数の無い関数の例として、たとえば下記のような文字表示をするだけの関数がある。

コード例
fun aisatu()  {
    println("こんにちは")
}

fun main() :Unit {
    aisatu()    
}


実行結果
こんにちは


ユーザ定義関数をmain関数よりも後ろに書いても、kotlinは読み取ってくれます。

コード例
fun gummo()  {
    println("おはよう")
}

fun main() :Unit {
    gummo()    
}


実行結果
おはよう

引数は読取専用[編集]

kotlinの関数の引数で宣言された変数は、基本的に読取専用です。そのため、下記のようにグローバル書き換えをしようとしても、エラーになり不可能です。

エラーになるコード例
var i : Int = 30 // グローバル変数として宣言

fun test(i: Int) : Int {
    i = i + 5 // ここでエラー
    println("いまユーザ関数の中")
    println(i)
    return 1
}

fun main() {
    var i : Int 
    i =10
    
    test(i)
    println("いまmain関数")    
    println(i)
}

たとえ同名の変数をグローバル変数で宣言していようが、引数で宣言された数の書き換えは不可能です。


もし、グローバル変数をユーザ定義関数で書き替えたい場合には、下記コードのように呼び出し時に、その引数名は与えないで、呼び出しします。

コード例
var i : Int = 30

// 引数が無い事に注目
fun test() : Int {
    i = i + 5 
    println("いまユーザ関数の中")
    println(i)
    return 1
}

fun main() {
    var i : Int 
    i =10
    
    test() // グローバル変数をいじるので、呼び出し側の引数を消す
    println("いまmain関数")    
    println(i)
}
実行結果
いまユーザ関数の中
35
いまmain関数
10

なお、ユーザ定義関数側でグローバル変数をいじっているので、ユーザ定義関数で参照される「i」は、main関数の「10」ではなく、グローバル変数の「30」および計算結果(+5)の「35」です。

また、main関数側でも別途iを宣言してあるので、main関数に戻った時にはiは「10」に戻ります。(詳しくは後述の「ローカル変数」の節で説明します。)


ローカル変数[編集]

ある関数の中で、呼び出し元やグーバル変数ですでに使用した変数と同じ変数名の変数をvar宣言する事ができますが、既存の変数とは別の、宣言場所のその関数内限定での変数として扱われ、このような仕組みを「ローカル変数」といいます。

コード例
fun test() : Int {
    var i : Int = 40
    i = i + 5 
    println("いまユーザ関数の中")
    println(i)
    return 1
}

fun main() {
    var i : Int 
    i =10
    
    test()
    println("いまmain関数")    
    println(i)
}
実行結果
いまユーザ関数の中
45
いまmain関数
10

ユーザ定義関数の中の「i」は、main関数の「i」とは別物です。

なので、ユーザ定義関数側でiが40になったり45になったりしても、ユーザ定義関数の実行が終わりmain関数に戻った際には、iの値は10に戻ってしまいます(main関数内でのユーザ定義関数の呼び出し直前のiの値が「10」なので、直前の値に戻る)。