[Day 5] 函數 (function)
function 的結構
先來解釋,一個 function 的結構會長這樣
其中以下是 function 的可見性修飾符號
- public: 其實可以不用寫,fun 預設就是 public,代表是隨處都可以看見
- private: 在同一 class 下可以看見
- protected: 在同一 class 或 class 的子 class 下可以看見
- internal: 在相同 module 下可以看見
fun - 代表 function 宣告
demoFun - function 名稱
(name: String,num: Int) - 這些是要傳入的參數和型態
:String - 最後是這個 function 要回傳的結果變數型態
Module
因為上面有提到 module,module 意思是
- IntelliJ IDEA 模組;
- Maven 專案;
- Gradle 源集;
- 使用 Ant 任務呼叫編譯的一組檔案。
簡單來說,就是某種建構工具的一個專案
函數 (function)
最普通的函數的寫法如下
fun getNumber2():Int { // 對的方式
return 100
}
拿掉回傳值的宣告可以嗎?答案是不行的
提示的訊息是說,這個 function 預期的回傳值型態是 Unit,什麼是 Unit 類型呢?
Unit 類型( function type)
Unit 就是我們在 Java 中常常看到的 void 的宣告,意思就是這個 function 不回傳值,為什麼要多一個 Unit 的型態來呢? 因為在以往 Java 的時候,void 因為不是一個變數型態而無法做出相對應的泛型,所以 Kotlin 為了泛型的這個問題,才創造了這個變數型態,預設不寫,回傳值就是 Unit 類型
single-expression function
函數也可以寫成如下,這個叫做 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 value (預設值)
我們也可以在參數列上,直接給予預設值
這樣的方式可以大大的增加 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
named paramter (具名參數)
有時候我們要呼叫 function 的時候,太多參數時,照順序傳入很麻煩的話,也可以直接指定我們要傳入哪一個參數
fun sum(a: Int, b: Int, c: Int = 10) = a + b + c
println(sum(b = 2, c = 1, a = 5)) // 8
function overloading (函數重載)
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 類型
Nothing 類型其實類似 Unit,但不同的是,宣告 Nothing 類型,結果會拋出 Exception,為什麼要這樣做呢? 其實我聽到會拋出 Exception...我是想,我應該這輩子不會使用吧XD
但驚人的事原來還是有用處的,我們可以找到 Kotlin 有內建一個 TODO 的函數,用來表示待辦事項,還未寫的程式
會發現 TODO() 這個 function 回傳類型就是 Nothing,這樣宣告有什麼好處呢?如果編譯器看到Nothing 類型就不會繼續執行了,所以其實 Nothing 還是有它的作用在的....長知識啊
反引號的 function name
通常在寫測試程式的時候會這樣使用,之後來講 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! 我們明天見!
今日練習的程式在這: 請點我