【Kotlin學習之旅】Kotlin的型別別名typealias

2020-08-13 20:59:37

一、型別別名typealias介紹

Kotlin提供了類似於C語言的typedef 的功能:可以爲已有的型別指定另一個可讀性更強的名字。Kotlin提供了typealias來定義型別別名。

typealias語句的語法格式爲:

typealias 型別別名 = 已有型別

如果型別名稱太長,你可以另外引入較短的名稱,並使用新的名稱替代原型別名。

  • 它有助於縮短較長的泛型型別。 例如,通常縮減集合型別是很有吸引力的:
// 爲Set<Network.Node> 指定更短的別名NodeSet 
typealias NodeSet = Set<Network.Node>
// 爲MutableMap<K, MutableList<File>> 指定更短的別名FileTable<K>
typealias FileTable<K> = MutableMap<K, MutableList<File>>

接下來即可直接使用NodeSet 和FileTable 命名變數。

var set : NodeSet 
var table : FileTable<String> 
  • 你可以爲函數型別提供另外的別名:
typealias MyHandler = (Int, String, Any) -> Unit

typealias Predicate<T> = (T) -> Boolean
  • 你可以爲內部類和巢狀類建立新名稱:
    很多時候,我們也可以通過定義別名爲內部類起一個更短的名字。例如如下程式。
class A {
    inner class Inner
}
class B {
    inner class Inner
}
//爲A.Inner內部類知道別名
typealias AInner = A.Inner
//爲B.Inner內部類知道別名
typealias BInner = B.Inner

fun typealiasTest(){
    // 使用AInner 定義變數、呼叫物件
    var a : AInner = A().AInner()
    // 使用BInner 定義變數、呼叫物件
    var b = B().BInner()
}

在这里插入图片描述

二、Kotlin自身使用的別名功能

Kotlin自身大量利用別名這個功能。比如Kotlin利用別名建立了Kotlin類和Java類之間的關係。

如下程式碼是Kotlin集合體系中定義的別名。

// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available

package kotlin.collections

@kotlin.SinceKotlin public typealias ArrayList<E> = java.util.ArrayList<E>

@kotlin.SinceKotlin public typealias HashMap<K, V> = java.util.HashMap<K, V>

@kotlin.SinceKotlin public typealias HashSet<E> = java.util.HashSet<E>

@kotlin.SinceKotlin public typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>

@kotlin.SinceKotlin public typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>

@kotlin.SinceKotlin public typealias RandomAccess = java.util.RandomAccess

在这里插入图片描述

三、Lambda表達式別名

與Java相比,Kotlin的Lambda表達式是一個差異性比較大的特色功能:

Java的Lambda表達式的型別是函數式介面,而Kotlin的Lambda表達式的型別之間就是函數型別。

因此Kotlin也允許爲Lambda表達式的型別指定別名。如下程式碼所示:

//爲 (T) -> Boolean 型別指定別名  Predicate<T>
typealias Predicate<T> = (T) -> Boolean

fun foo(p: Predicate<Int>) = p(42)

fun main() {
    val f: (Int) -> Boolean = { it > 0 }
    println(foo(f)) // 輸出 "true"
    
    //使用 Predicate<Int> 定義變數,該變數的值是一個Lambda表達式
    val p: Predicate<Int> = { it > 0 }
    
    // 爲filter() 方法傳入p參數,只保留大於0的數位
    println(listOf(1, -2, 4, 5, 6, 7 ).filter(p)) // 輸出 "[1]"
    
    
    
    //使用 Predicate<String> 定義變數,該變數的值是一個Lambda表達式
    val p2: Predicate<String> = { it.length > 4 }
    
    // 爲filter() 方法傳入p參數,只保留長度大於4的字串
    println(arrayOf("Java", "Kotlin", "Python", "C", "C++","OuyangPeng").filter(p2))
    
}

執行結果爲:

true
[1, 4, 5, 6, 7]
[Kotlin, Python, OuyangPeng]

在这里插入图片描述