當Android遇上Kotlin — Day2

函數的使用技巧

  • 利用對函數設定參數的預設值,在Kotlin中可以避免函數的過度重載
fun <T> joinToString(
collection: Collection<T>,
separator: String = ", ", // 預設參數值
prefix: String = "",
postfix: String = ""
): String
// 現在你可以使用以下方法來進行函數的調用
joinToString(list)
joinToString(list, ", ", "", "")
joinToString(list, ";")
joinToString(list, prefix = "#")
  • 一般在Java中常見的靜態工具類別,在Kotlin中如何實現
  • 在Kotlin中,你可以將函數放置在文件的最頂層開頭位置,而不需要創建額外無意義的Util類別
// Java
public class StringUtils {
public static String joinToString(...) { ... }
}
// Kotlin
fun joinToString(...): String { ... }
// 如果需要對這些function進行歸類時,可以使用改变文件的类名方式
@file:JvmName("StringFunctions")
package strings
fun joinToString(...): String { ... }
// 呼叫時一樣需要進行import
import strings.StringFunctions
StringFunctions.joinToString(...)
  • 擴展函數是一個可以被類別成員調用的一個函數,但定義在外部類別
// 在函數前添加需要擴展的類別或interface (receiver type)也就是接收型態
// 在後方的this則代表著擴展函數的值(receiver object)也就是接收物件
fun String.lastChar(): Char = this.get(this.length - 1)
// 此時的"Kotlin"同時為接收型態與接收物件
print("Kotlin".lastChar())
輸出:n
// 其實就有點像
var text: String = get() { field.length - 1 }
fun lastChar(text: String): Char {
return text
}
// 其實就等於擴展屬性的一種,只是以下擴展並無任何作用
val String.lastChar: Char
get() = get(length - 1)
// 可改為用StringBuilder來進行接收
var StringBuilder.lastChar: Char
get() = get(length - 1) // 進行屬性呼叫
set(value: Char) { // 進行屬性設定
this.setCharAt(length - 1, value)
}
  • 使用擴展函數來做為傳入的第一個參數值
// Collection<T>來表示一個擴展函數
// this來表示擴展函數的接收物件,也就是T類型的集合
fun <T> Collection<T>.joinToString( 
separator: String = ", ",
prefix: String = "",
postfix: String = ""): String {
val result = StringBuilder(prefix)
for ((index, element) in this.withIndex()) {
if (index > 0) result.append(separator)
result.append(element)
}
result.append(postfix)
return result.toString()
}
  • 擴展函數是不可以被override的,因為當這個類別中有個成員函數和擴展函數有相同名稱時,成員函數總是優先被呼叫。
  • 可變參數(vararg)是一個可以接收任意個參數的函數
//Java
public static int sum(int... numbers) { ... }
//Kotlin
fun listOf<T>(vararg values: T): List<T> { ... }
  • 中綴調用(infix call),使用條件必須在
1.該函數為類別中的成員函數或擴展函數
2.必須只有一個參數
3.函數前綴詞有infix的修飾符
例如:
infix fun Any.to(other: Any) = Pair(this, other)
正常寫法為:1.to("one")
中綴寫法為:1 to "one"
  • Local Functions
class User(val id: Int, val name: String, val address: String){
   // 擴展函數
fun User.validateBeforeSave() {
fun validate(value: String, fieldName: String) {
if (value.isEmpty()) {
throw IllegalArgumentException(
"Can't save user $id: empty $fieldName")
}
}
validate(name, "Name")
validate(address, "Address")
}

fun saveUser(user: User) {
//呼叫擴展函數
user.validateBeforeSave()
// Save user to the database
}
}
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.