不知道如何測試下列語法可以參考如何使用Android Studio 測試資料?
- 操作符重載
- 資料區間用法
- map使用方法
- 內部靜態變數
- 靜態變數
- 當資料如果是?型態宣告
- 資料使用!!,強制將Int?轉Int
- data class用法
- 強制轉型
- run、with、apply、also用法
這裡只舉例,因為數量很多,其他請各位舉一反三囉,參考此處
class ReloadOperator(var arg1: Double, var arg2: Double) { operator fun plus(value: Double): ReloadOperator { return ReloadOperator(arg1+value, arg2+value) } operator fun invoke(): Double { return arg1+arg2 } } val test = ReloadOperator(10.0,30.0) val data = test + 10.0 //會執行plus //data()會執行invoke() println("data.arg2 = ${data.arg2} data() = ${data()}") //data = 40.0 data2 = 60.0
for(index in 0 until 5) { println("index = $index") //0 1 2 3 4 } for(index in 0..5) { println("index = $index") //0 1 2 3 4 5 } for(index in 10 downTo 0 step 3) { println("index = $index") //10 7 4 1 }
//可讀可寫 mutableMapOf //只可讀 mapOf //第一種:可讀可寫 val map = mutableMapOf("a" to 20, "b" to "AAA", "c" to 10.0) map["a"] = 32 println("map ${map["a"]}") //打印 map 32 //第二種:可讀不可寫 val map2 = mapOf("a" to 1, "b" to 2, "c" to 3) map2["a"] = 32 //錯誤導致無法編譯 println("map ${map["a"]}") //打印 map 1 //遍歷map for((key, value) in map2) { println("key = $key, value = $value") }
class AAA { companion object { const val data1 = 1 const val data2 = 2 init { System.loadLibrary("native-lib") } } } class BBB { fun setData(data: Int) { AAA.data1 = 2 if(AAA.data2 == 2) { println("data = ${AAA.data2}") } } }
object SDK { var init: Boolean? = false } class main { fun initData(flag: Boolean?) { if(SDK.init != null) { SDK.init = true } } }
fun isCount(data: Int?): Int { return data ?: return -1//如果data is null回傳-1 } @Test fun test1() { println(isCount(0))//0 println(isCount(null))//-1 }
舉例強制將Int?轉Int,注意使用!!,如果是null將會發生異常
private var data: Int? = 1 fun checkData(): Int { if(data != null) { return data!! } return -1 } //多個val data就可以去掉!!囉 private var data: Int? = 1 fun checkData(): Int { val data = data if(data != null) { return data } return -1 }
data class Book(var name: String, var price: Int) { fun plusPrice(value: Int) { //plus 是將price+value在返回值 price = price.plus(value) } fun minusPrice(value: Int) { //minus 是將price-value在返回值 price = price.minus(value) } } val book: Book? = Book("AABBCC", 59) println("price = ${book?.price}") //輸出59 book?.plusPrice(10) println("price = ${book?.price}") //輸出69 book?.minusPrice(20) println("price = ${book?.price}") //輸出49 data class TestDataClass( var name: String = "Apple", val value: Int = 0 ) class TestClass( val name: String = "Apple", var value: Int = 0 ) @Test fun test1() { val testDataClass = TestDataClass().also { it.name = "Windows" } val testClass = TestClass().also { it.value = 1 } //data class覆寫了toString println(testDataClass.toString()) println(testClass.toString()) //打印如下 //TestDataClass(name=Windows, value=0) //com.xxx.ExampleUnitTest$TestClass@2fd66ad3 //多了快速取值的方法 val (name, value) = testDataClass println("name = $name, value = $value") //打印如下 // name = Windows, value = 0 //克隆一份一模一樣資料的 val testDataClass1 = testDataClass.copy() println(testDataClass) println(testDataClass1) //打印資料如下 //TestDataClass(name=Windows, value=0) //TestDataClass(name=Windows, value=0) } //test2 與 test3比較就可以明顯看出class與data class的不同了 @Test fun test2() { val testDataClass = TestDataClass().also { it.name = "Windows" } val testDataClass1 = TestDataClass().also { it.name = "Windows" } //記憶體位置不同 println(testDataClass === testDataClass1) //false //相同物件 println(testDataClass == testDataClass1) //true println(testDataClass.hashCode()) //-1050734083 println(testDataClass1.hashCode()) //-1050734083 明顯看到相同 testDataClass1.name = "Apple" //變更testDataClass1 名稱 println(testDataClass === testDataClass1) //false println(testDataClass == testDataClass1) //false println(testDataClass.hashCode()) //-1050734083 println(testDataClass1.hashCode()) //1967772678 println(testDataClass.toString()) //TestDataClass(name=Windows, value=0) println(testDataClass1.toString()) //TestDataClass(name=Apple, value=0) } @Test fun test3() { val testClass = TestClass().also { it.name = "Windows" } val testClass1 = TestClass().also { it.name = "Windows" } //記憶體位置不同 println(testClass === testClass1) //false //相同物件 println(testClass == testClass1) //false println(testClass.hashCode()) //1375995437 println(testClass1.hashCode()) //1338841523 明顯看到不同 testClass1.name = "Apple" //變更testClass1 名稱 println(testClass === testClass1) //false println(testClass == testClass1) //false println(testClass.hashCode()) //1375995437 println(testClass1.hashCode()) //1338841523 } //此處有個重點在Kotlin與Java上的差異 1.Referential Equality 參考性 與記憶體有關 2.Structural Equality 結構性 Object相等 Java Referential Equality == Structural Equality equals Kotlin Referential Equality === Structural Equality == , equals
fun main() { var data1: String = "1234" var data2: Int = 20 onDataChange(data1) onDataChange(data2) } fun onDataChange(data: Any) { val data1: String? = data as? String val data2: Int? = data as? Int if(data1 != null) { //有資料 println("{data1 ${data1}}") } if(data2 != null) { //有資料 println("{data2 ${data2}}") } }
run+let,run回傳最後一行給let,let再回傳最後一行,給result做為結果
data class Book(var name: String, var price: Int) { fun plusPrice(value: Int) { //plus 是將price+value在返回值 price = price.plus(value) } fun minusPrice(value: Int) { //minus 是將price-value在返回值 price = price.minus(value) } } //第一種 val book: Book? = Book("apple", 10) val result = book?.run { //run內部時,是this println("this $this ------- name $name") true }.let {//run 和 with都是回傳最後一行 //此時的it是true println("let $it") it != null } println("result $result") //打印 //this Book(name=apple, price=10) ------- name apple //let true //result true //第二種 val book: Book? = null val result = book?.run { //run內部時,是this println("this $this ------- name $name") true }.let {//run 和 with都是回傳最後一行 //此時的it是true println("let $it") it != null } println("result $result") //此處run不會進入,因為run不會處理null,如果要確保let不是null改用with //打印let null //result false
當with是null時,最後回傳的依然是最後一行
因為with的內部可以有?
//第一種 val book: Book? = null val result = with(book as Book?) { println("this $this") true }.let { //因為with可以在那處理null //不會因為null直接到let //所以基本上就是with的最後一行資料進來 it != null } println("result $result") //打印 //this null //result true //第二種 val book: Book? = Book("Apple", 10) val result = with(book as Book?) { println("this $this") true }.let { //因為with可以在那處理null //不會因為null直接到let //所以基本上就是with的最後一行資料進來 it != null } println("result $result") //打印 //this Book(name=Apple, price=10) //result true
apply 可以整理完資料將自己返回
val list = ArrayList().apply { add("1234") add("3456") }.let { listTemp ->//it可以像這樣改名字 //整理好的資料是it println("let it $listTemp, size ${listTemp.size}") //此時輸出size = 2 listTemp } println("list -> $list, size -> ${list.size}") //let it [1234, 3456], size 2 //list -> [1234, 3456], size -> 2
also 與apply一樣的意思
只是變成it, it可以像上面listTemp一樣改名字
val list = ArrayList().also { //it是剛建立好的ArrayList it.add("1234") it.add("3456") println("this $it size ${it.size}") } println("list $list, size ${list.size}") //this [1234, 3456] size 2 //list [1234, 3456], size 2
上面皆是版本ext.kotlin_version = “1.5.0″測試的
更多相關可以參考這裡
相關文章
Android Kotlin 基本語法1 | Android Kotlin 基本語法3 |
1. var 可變變數 2. val 不可變更參數 3. Array 用法 4. ArrayList 用法 5. List的filter、sort、map、forEach 6. when 用法 7. fun 函式用法 8. if 表達式 9. for 表達式 10. 擴充函數(自定義函式) | 1. class多建構式 2. 內部class用法 3. interface 4. enum class 用法 5. sealed class 用法 6. open 用法 |
Android Kotlin 基本語法4 | Android Kotlin Classes and Objects-1 |
1. 為基礎類型新增函式 2. Abstract技巧使用 3. throw使用方法 4. 利用let特性處理資料型態? 5. 快速初始化Array 6. 快速將兩個資料交換 7. 自定義待處理的fun 8. 幫loop設定標籤 | 1. 多個class與執行順序 2. init與constructor執行優先序 3. open繼承與禁止繼承 4. 不同的寫法,影響override能不能改變值 5. 繼承與當前Class執行順序 6. 由inner class去找parent的super 7. 繼承多個class時,選擇指定的Parent 8. private protected public internal修飾符差異 |
Android Kotlin Classes and Objects-2 | Android Kotlin 委託屬性 |
1. 幫List新增swap功能 2. 擴充外加函式,幫助程式簡化 3. T,多類型引入 4. T搭配in、out使用 5. 1個對象的object用法 6. 類型別名 7. 內聯類 8. 委託 | 1. 變數委託 2. lazy懶加載用法+String.split 3. 可觀察屬性observable 4. 委託內建map 5. 本地委託屬性,此方法可以減少加載 6. 委託屬性,唯獨與可讀可寫的方法 7. 將舊方法棄用 |
訂閱Codeilin的旅程,若有最新消息會通知。
廣告