先來解釋,一個 function 的結構會長這樣
其中以下是 function 的可見性修飾符號
fun - 代表 function 宣告
demoFun - function 名稱
(name: String,num: Int) - 這些是要傳入的參數和型態
:String - 最後是這個 function 要回傳的結果變數型態
因為上面有提到 module,module 意思是
簡單來說,就是某種建構工具的一個專案
最普通的函數的寫法如下
fun getNumber2():Int { // 對的方式
return 100
}
拿掉回傳值的宣告可以嗎?答案是不行的
提示的訊息是說,這個 function 預期的回傳值型態是 Unit,什麼是 Unit 類型呢?
Unit 就是我們在 Java 中常常看到的 void 的宣告,意思就是這個 function 不回傳值,為什麼要多一個 Unit 的型態來呢? 因為在以往 Java 的時候,void 因為不是一個變數型態而無法做出相對應的泛型,所以 Kotlin 為了泛型的這個問題,才創造了這個變數型態,預設不寫,回傳值就是 Unit 類型
函數也可以寫成如下,這個叫做 single-expression function,返回的類型,大括號,return 都可以省略,直接表示一個 function
fun getNumber3(): Int = 100
fun getNumber4() = 100
fun getNumber5(num: Int) = when (num) {
0 -> "it's zero"
in 1..99 -> "it's between 1 to 99"
else -> "not match"
}
println(getNumber5(1000)) // not match
我們也可以在參數列上,直接給予預設值
這樣的方式可以大大的增加 function 呼叫的彈性
// default values
fun sum(a: Int, b: Int, c: Int = 10) = a + b + c
println(sum(1, 2, 3)) // 6
println(sum(1, 2)) // 13
有時候我們要呼叫 function 的時候,太多參數時,照順序傳入很麻煩的話,也可以直接指定我們要傳入哪一個參數
fun sum(a: Int, b: Int, c: Int = 10) = a + b + c
println(sum(b = 2, c = 1, a = 5)) // 8
Kotlin 中 overloading 跟在 Java 一樣,function 名稱都一樣的狀況下,就是靠參數數量不同來區分
fun overload() {
println("overloading")
}
fun overload(num: Int) {
println("overloading num: $num")
}
fun overload(num: Int, isTrue: Boolean) {
println("overloading num: $num, is true: $isTrue")
}
overload() // overloading
overload(1) // overloading num: 1
overload(2, false) // overloading num: 2,is true: false
overload(isTrue = true, num = 10) // overloading num: 10,is true: true
Nothing 類型其實類似 Unit,但不同的是,宣告 Nothing 類型,結果會拋出 Exception,為什麼要這樣做呢? 其實我聽到會拋出 Exception...我是想,我應該這輩子不會使用吧XD
但驚人的事原來還是有用處的,我們可以找到 Kotlin 有內建一個 TODO 的函數,用來表示待辦事項,還未寫的程式
會發現 TODO() 這個 function 回傳類型就是 Nothing,這樣宣告有什麼好處呢?如果編譯器看到Nothing 類型就不會繼續執行了,所以其實 Nothing 還是有它的作用在的....長知識啊
通常在寫測試程式的時候會這樣使用,之後來講 spring boot 例子的時候會再看到!
像下面這個例子,函數名稱就用單引號刮起來了,然後在單引號裡面可以直接用一個句子來描述你的測試程式
@Test
fun `greet with Dolly returns 'Hello, Tim!'`() {
client.get().uri("/rest?name=Tim")
.exchange()
.expectStatus().isOk
.expectBody<Greeting>()
.consumeWith { assertEquals("Hello, Tim!", it.responseBody?.message) }
}
今天就先講到這裡,今天講比較少一點 。
因為明天會一口氣來解釋匿名函數和 lambda! 我們明天見!
今日練習的程式在這: 請點我