Kotlin 程序員詞典:語句 VS 表達式

語句(statement)表達式(expression)是常常被錯誤理解的兩個重要術語。我們從解釋表達式這個術語開始。

表達式(Expression)

在 Kotlin 社區(qū),表達式術語通常和 kotlin 的單表達式函數(shù)(single-expression functions)聯(lián)系在一起:

fun bigger(a: Int, b: Int) = if(a > b) a else b

考慮到這一點,我們應該直觀地知道什么是表達式。 問題是,直覺可能會誤導我們。 讓我們從一個常見的定義開始:

在編程語言中,表達式是一個或者多個顯示的值、常量、變量操作數(shù)和函數(shù)的組合,編程語言能夠理解并計算產(chǎn)生另外一個值。

所以 1 + 1 是一個表達式,這和 sumOf(1, 2, 3) 是一樣的。注意一個表達式可以包含另外一個表達式。例如,表達式 sumOf(1, 2*3) 包含表達式 2*3。表達式是代碼(會返回值的代碼)的每一部分。注意在 Kotlin 中,每一個函數(shù)都會至少返回 Unit,所以每一個函數(shù)調用都是一個表達式。那是否意味著所有一切都是表達式?絕對不是!這里有幾個示例:

  • 變量聲明不是表達式val a = 10
  • 在 kotlin 中變量或者屬性賦值不是表達式a = 10
  • 類聲明不是表達式class A {}

它們都不是表達式,但是它們都是語句。

語句(Statement)

我們從另一個常見的定義開始:

在計算機程序中,語句是命令式編程語言的最小獨立部件,它描述可被執(zhí)行的任務。

我覺得這還不是很清晰,所以我還會展示另一個示例。我們來看看下面的代碼:

val bestUser = users.filter { it.passing }
      .maxBy { it.meanScore }
println("${bestUser.name} ${bestUser.surname}")

這里我看到了很多表達式,但是只有兩個語句。第一個是處理 users 集合并將結果存儲到 bestUser 變量。第二個語句是打印這個用戶的姓名。最簡單的判斷方法就是:Java 中以分號結束的代碼都是語句。在 Kotlin 中它通常是單行代碼,但是我們也可以在一行代碼中編寫多個語句(如果我們使用分號),我們也可以編寫占用多行代碼的語句

val bestUsers = users.filter { it.passing }
      .sortedBy { -it.meanScore }
      .take(10)
print("The best students are: "); println(bestUsers.joinToString());

這里有3個語句。第一個是處理 users 以獲得最好的用戶,第二個是打印 “The best students are: ”,第三個是打印 bestUsers 拼接出來的一個字符串。

注意單個表達式同時也是語句。就像下面這個 updateUser 函數(shù)調用:

updateUser(user)

這樣的單個表達式稱為表達式語句(expression statement)。

有趣的現(xiàn)象是在純函數(shù)式編程中沒有語句。只有表達式。

為什么要區(qū)分它們?

現(xiàn)在當你理解了什么是表達式語句之后,你會發(fā)現(xiàn)當你在圖書或者文章中描述代碼時是多么的有用。我們一起來看一個例子:

fun showUsers(users: List<User>?) {
    users ?: return
    val adapters = users.map { UserAdapter(it, ::onUserClicked) }
    list.adapter = UserListAdapter(adapters)
}

在上面的代碼片段中,我們可以這樣描述 showUsers 是怎樣定義的。在它的函數(shù)體的第一個語句中,檢查 users parameter 是否為 null。注意在 Kotlin 中函數(shù)參數(shù)是只讀的(read-only),這一斷言將 users 轉換成一個非空值,其函數(shù)的剩余代碼中它都不會為 null。所以在第二個語句中,我們可以直接使用而不需要做任何解壓。注意我們在通過 UserAdapter(it, ::onUserClicked) 表達式將 users 轉換成 adapters 時,我們還將 onUserClicked 函數(shù)作為參數(shù)傳遞。在最后一個語句中,我們將 list 的 adapter 指定為一個新創(chuàng)建的 UserListAdapter 實例。它包含了為所有 users 創(chuàng)建的 adapters。

注意在描述代碼的過程中,語句表達式幫助我們準確的表達想法。

表達式在 Java 和 Kotlin 中有何不同?

注意,在 Kotlin 和 Java 中表述什么是表達式以及什么不是表達式時,兩者有基本的差別。所有的 Kotlin 函數(shù)調用都是表達式,因為他們至少會返回 Unit。調用沒有定義任意返回值的 Java 函數(shù)時不是表達式。Kotlin 中變量賦值(a = 1不是表達式,但是在 Java 中則是,因為這個操作之后會返回被賦予的值(在 Java 中,你可以 a = b = 2 或者 a = 2 * (b = 3)))。在 Java 中所有的控制結構(if, switch都不是表達式,而在 Kotlin 中允許 if, when , try 返回值:

val bigger = if(a > b) a else b
val color = when {
    relax -> GREEN
    studyTime -> YELLOW
    else -> BLUE
}
val object = try {
    gson.fromJson(json)
} catch (e: Throwable) {
    null
}

本文譯自Kotlin programmer dictionary: Statement vs Expression

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容