開始學習用Kotlin 來寫Android,因為已經有寫Java的經驗,Kotlin語法的部分只針對自己覺得比較特殊的部分做一個筆記記錄下來,方便未來查詢檢視。
主要是在 udemy 平台上學習Kotlin所記錄下的筆記,有興趣者可以參考這堂課程。
var : 變數宣告
val : Immutable 變數宣告,以val 宣告的變數則不可重新指定新的值
型別宣告: Kotlin 會自動推斷一些變數型別,但也可以透過宣告方式來指定:
var age: Int = 24;
age = "string" // <= throw error
宣告起始值為 null 之變數方法:
val age: Int = null; // <= Error here
val age: Int? = null; // Correct
如果宣告一個變數初始值為 null ,在後續調用 function 時,會出現錯誤提示,原因是我們宣告的變數可能在runtime 時,內容仍為null,調用null的function 會導致 nullPointerException 錯誤
val name: String? = null;
val.length // <= error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
解決方式有兩種
使用 !!
使用 ?
如果是Mutable變數,可以透過加入if 判斷的方式,Kotlin compiler 就不會報錯(該方式僅限於區域變數,若為全域變數,這方法無效)
val name: String = null
val name2: String? = "Kotlin"
println(name!!.length) // <= kotlin.KotlinNullPointerException
println(name?.length) // <= null
if(name2 != null){ // local variable only,若name2為全域變數則會報錯
println(name2.length); // <= compiler 會知道進到這邊的情況下 name2 一定不會是 null
}
If 用法與 Java等其他語言相同,這邊紀錄比較特別的部分:
val x: Int = 20
val y = if(x < 10){
println("LT 10")
"LT 10"
}else if(x >=10 && x<20) {
println("GT 10 abd LT 20")
"GT 10 abd LT 20"
}else {
println("GTE 20")
"GTE20"
}
println(y)
類似switch,可以分為 when(expxression){statement} 或是 when {statement},後者與其他程式語言相同
val price:Int = 30
// 第一種用法
when(price){
0,1 -> println("For free today") // 0或1
in 2..19 -> println("On sale") // 在 2 - 19的區間;如果是不要再2-19的區間,可以改為 !in 2..19
in 20..29 -> println("Normal price") // 在 20到 29 區間
10+20 -> println("Slightly overpriced") // 左方可以是expression或function
else -> println("Overpriced") // 等同default value
}
// 第二種用法,執行內容相同
when{
price == 0 || price ==1 -> // 0或1
price in 2..19 -> println("On sale")
price in 20..29 -> println("Normal price")
price == 20+10 -> println("Slightly overpriced"
else -> println("Overpriced")
}
// 與 if一樣的特殊用法:
val x = when(..)...
Kotlin的Collections 是建立在Java的Collections上,並再加入更實用的library functions,並且有Mutable與Immutable Collections的概念。
// Array
val array = arrayOf(1,2,3,4) // 一般陣列宣告
val intArray = intArrayOf(1,2,3,4) // Kotlin 提供了 primitive type array
val doubleArray = doubleArrayOf(1.0,2.0,3.0,4) // double array
// **下列collection 會區分為 Mutable與Immutable**
// List
val list = listOf(1,2,3,4) // Immutable list,無法針對內容再作修改
val mutableList = mutableListOf(1,2,3,4) // mutable list,可修改內容
list[0] = 1 // <= compile error
mutableList[0] = 99 // <= success
// 可以透過 joinToString 方法將collection 印出
list.joinToString() // 1,2,3,4
mutableList.joinToString() // 99,2,3,4
// Map
val map = mapOf(Pair(1, "Kotlin"), Pair(2, "Android"))
val mutableMap = mutableMapOf(Pair(1,"Kotlin"), Pair(2, "Android"))
// Map 提供一個更直覺地宣告方式,透過 to 來宣告,下列宣告方式與上方相同:
val mutableMap = mutableMapOf(1 to "Kotlin", 2 to "Android") // 結果與前面宣告方式的結果相同
// Set
val set = setOf(1,2,1,2,3) // 僅可取內容,但不可修改內容
val mutableSet = mutableSetOf(1,2,1,2,3) // mutable set 才會提供add, remove之類的 function
從上面不難看出,除了陣列以外,其他的collection 類別都會區分為 mutable與immutable,宣告差異就在前面加上mutable與否來決定要以mutable還是immutable 方式來宣告。
直接看語法:
// range
for(i in 1..10){
println("$i ") // print 1 to 10
}
// iterable
for(s in "Kotlin"){
println("$s "); // K o t l i n
}
val list = listOf("a", "b", "c")
for(i in list){
println("$i ") // a b c
}
// step
for(i in 1..10 step 2){
println("$i ") // i add by 2. 1 3 5 7 9
}
// reverse
for(i in 10 downTo 1 step 2){
println("$i ") // from 10 down to 1 10 8 6 4 2
}
直接看程式吧
var i = 0
while(i <=10){
println("$i ") // print 0 to 10
i++;
}
var j =0
do{
println("$j ")
j++;
}while(j<=10)
fun permitEntrance(age: Int): Boolean{
return age>=18
}
// 等同於
fun permitEntrance(age:Int):Boolean => age>=18
permitEntrance(20) // <= true
// vararg 宣告表示可傳入多個內容
fun permitEntrance(vararg ages: Int){
// any表示在ages內每一個value
return ages.any {age => age>=18}
}
permitEntrance(18, 19, 20) // true
在宣告function 時, 可以對參數宣告預設值,在呼叫時若未傳入任何內容,則會以使用預設值
concat(listOf("Android", "Kotlin")) // <= Android,Kotlin
fun concat(texts: List<string>, seperator:String = ",") = texts.joinToString(seperator)
</string>
在參數傳遞時,也可以下列方式傳遞,直接指定哪些內容要對應到哪些參數名稱:
concat(seperator = ";". values = listOf("Android", "Kotlin")) // <= Android,Kotlin
fun concat(texts: List<string>, seperator:String = ",") = texts.joinToString(seperator)
Exception 用法與Java差不多,但也多了與 if-else 相同的使用方式,這邊僅記錄較特別的部分:
fun main(args: Array<string>){
var input = try {
getExternalInput() //return value
}catch(e:Exception){
e.printStackTrace()
"" // return value when exception caught
}finally{
println("Finished")
}
println(input)
}
fun getExternalInput():String{
throw IOException("Could not read external input")
}