不知道如何測試下列語法可以參考如何使用Android Studio 測試資料?
- 幫List新增swap功能
- 擴充外加函式,幫助程式簡化
- T,多類型引入
- T搭配in、out使用
- 1個對象的object用法
- 類型別名
- 內聯類
- 委託
快速兩資料交換參考Android Kotlin 基本語法3
fun MutableList.swap(index1: Int, index2: Int) { val tmp = this[index1] this[index1] = this[index2] this[index2] = tmp } fun MutableList.swap2(index1: Int, index2: Int) { //用Android Kotlin 基本語法3那篇的,快速兩資料交換的方法 this[index1] = this[index2].also { this[index2] = this[index1] } } @Test fun test() { val list = mutableListOf(10, 20, 30) list.swap(0, 2) list.forEach { println("A = $it") } /* 打印 A = 30 A = 20 A = 10*/ list.swap2(0, 2) list.forEach { println("B = $it") } /* 打印 B = 10 B = 20 B = 30*/ }
class Host(val hostname: String) { fun printHostname() { print(hostname) } } class Connection(val host: Host, val port: Int) { fun printPort() { print(port) } //利用此方法幫助程式簡化 fun Host.printConnectionString() { printHostname() print(":") printPort() } fun connect() { host.printConnectionString() } } @Test fun test() { Connection(Host("kotl.in"), 443).connect() }
class Box(t: T) { var value = t } @Test fun test() { val box = Box("123") }
//T搭配out用法 interface Source { //in -> 引入T, out -> return T, 此處為"return T" fun nextT(): T } fun demo(callback: Source) { val objects: Source = callback println(objects.nextT())//打印"hello" } val sourceCallback = object : Source{ override fun nextT(): String { return "hello" } } @Test fun test() { demo(sourceCallback) } //T搭配in用法 interface Comparable { //in -> 引入T, out -> return T, 此處為"引入T" fun compareTo(data1: T, data2: T): Boolean } fun demo(x: Comparable) { //打印false println(x.compareTo(1.0, 2.0)) // Double是Number的子類型 //因此可以這樣賦予 val y: Comparable = x // OK! } @Test fun test2() { demo(object : Comparable{ override fun compareTo( data1: Number, data2: Number ): Boolean = data1 == data2 }) }
class C { // 私有函數內,返回的函數也是私有的 private fun foo() = object { val x: String = "x" } // 公有函數,內容也是公有 fun publicFoo() = object { val x: String = "x" } fun bar() { val x1 = foo().x // private fun 正常 val x2 = publicFoo().x // fun 錯誤 } }
//typealias 是重新將底層類型命名 //testString is String typealias testString = String class ExampleUnitTest { @Test fun test() { val data: testString = "1234" println(data) //print 1234 } }
7. 內聯類,為了減少大量程式碼的開銷
//inline在1.5版以後,不推薦使用的內聯類 //應改為下方 @JvmInline value class Password(val value: String) @Test fun test() { //securePassword運行的時候,內部會簡化成只代表String val securePassword = Password("Don't try this in production") println(securePassword) } var counter = 0 set(value) { if (value >= 0) field = value //field 就是backing fields } //還有支持一些基本用法 //但有一些限制,不能含有 backing fields //只能做簡單的計算(沒有lateinit/delegated屬性) @JvmInline value class Name(val s: String) { init { require(s.length > 0) { //require <= 0 //throw java.lang.IllegalArgumentException } } val length: Int get() = s.length fun greet() { println("Hello, $s") } } @Test fun test() { val name = Name("Kotlin") name.greet() // `greet` 方法會作為一個靜態方法調用 println(name.length) //屬性的get方法會作為一個靜態方法調用 } //內聯類允許繼承 interface Printable { fun prettyPrint(): String } @JvmInline value class Name(val s: String) : Printable { override fun prettyPrint(): String = "Let's $s!" } @Test fun test() { val name = Name("Kotlin") println(name.prettyPrint()) // Still called as a static method } //typealias 是重新將底層類型命名 //@JvmInline // value是生成新的類型 typealias NameTypeAlias = String @JvmInline value class NameInlineClass(val s: String) fun acceptString(s: String) {} fun acceptNameTypeAlias(n: NameTypeAlias) {} fun acceptNameInlineClass(p: NameInlineClass) {} @Test fun test() { val nameAlias: NameTypeAlias = "" val nameInlineClass: NameInlineClass = NameInlineClass("") val string: String = "" acceptString(nameAlias) //正常,因為typealias 是重新將底層類型命名 acceptString(nameInlineClass) //錯誤,內聯是新建新的類型,所以不等於String // And vice versa: acceptNameTypeAlias(string) //正常,因為typealias 是重新將底層類型命名 acceptNameInlineClass(string) //錯誤,內聯是新建新的類型,所以不等於String }
8. 委託(Delegation)
interface Base { val message: String fun print() } class BaseImpl(x: Int) : Base { override val message = "BaseImpl: x = $x" override fun print() { println(message) } } class Derived(b: Base) : Base by b { //by b -> 如果此處有override,以此處為優先 //若沒有override,則使用Base內預設的. override val message = "Message of Derived" } @Test fun test() { val b = BaseImpl(10) val derived = Derived(b) derived.print() println(derived.message) /* BaseImpl: x = 10 Message of Derived */ }
上面皆是版本ext.kotlin_version = “1.5.0″測試的
更多相關可以參考這裡
相關文章
Android Kotlin 基本語法1 | Android Kotlin 基本語法2 |
1. var 可變變數 2. val 不可變更參數 3. Array 用法 4. ArrayList 用法 5. List的filter、sort、map、forEach 6. when 用法 7. fun 函式用法 8. if 表達式 9. for 表達式 10. 擴充函數(自定義函式) | 1. 操作符重載 2. 資料區間用法 3. map使用方法 4. 內部靜態變數 5. 靜態變數 6. 當資料如果是?型態宣告 7. 資料使用!!,強制將Int?轉Int 8. data class用法 9. 強制轉型 10. run、with、apply、also用法 |
Android Kotlin 基本語法3 | Android Kotlin 基本語法4 |
1. class多建構式 2. 內部class用法 3. interface 4. enum class 用法 5. sealed class 用法 6. open 用法 | 1. 為基礎類型新增函式 2. Abstract技巧使用 3. throw使用方法 4. 利用let特性處理資料型態? 5. 快速初始化Array 6. 快速將兩個資料交換 7. 自定義待處理的fun 8. 幫loop設定標籤 |
Android Kotlin Classes and Objects-1 | Android Kotlin 委託屬性 |
1. 多個class與執行順序 2. init與constructor執行優先序 3. open繼承與禁止繼承 4. 不同的寫法,影響override能不能改變值 5. 繼承與當前Class執行順序 6. 由inner class去找parent的super 7. 繼承多個class時,選擇指定的Parent 8. private protected public internal修飾符差異 | 1. 變數委託 2. lazy懶加載用法+String.split 3. 可觀察屬性observable 4. 委託內建map 5. 本地委託屬性,此方法可以減少加載 6. 委託屬性,唯獨與可讀可寫的方法 7. 將舊方法棄用 |
訂閱Codeilin的旅程,若有最新消息會通知。
廣告