Kotlin 程序员词典:语句 VS 表达式

语句(statement)表达式(expression)是常常被错误理解的两个重要术语。我们从解释表达式这个术语开始。

表达式(Expression)

在 Kotlin 社区,表达式术语通常和 kotlin 的单表达式函数(single-expression functions)联系在一起:

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

考虑到这一点,我们应该直观地知道什么是表达式。 问题是,直觉可能会误导我们。 让我们从一个常见的定义开始:

在编程语言中,表达式是一个或者多个显示的值、常量、变量操作数和函数的组合,编程语言能够理解并计算产生另外一个值。

所以 1 + 1 是一个表达式,这和 sumOf(1, 2, 3) 是一样的。注意一个表达式可以包含另外一个表达式。例如,表达式 sumOf(1, 2*3) 包含表达式 2*3表达式是代码(会返回值的代码)的每一部分。注意在 Kotlin 中,每一个函数都会至少返回 Unit,所以每一个函数调用都是一个表达式。那是否意味着所有一切都是表达式?绝对不是!这里有几个示例:

  • 变量声明不是表达式val a = 10
  • 在 kotlin 中变量或者属性赋值不是表达式a = 10
  • 类声明不是表达式class A {}

它们都不是表达式,但是它们都是语句

语句(Statement)

我们从另一个常见的定义开始:

在计算机程序中,语句是命令式编程语言的最小独立部件,它描述可被执行的任务。

我觉得这还不是很清晰,所以我还会展示另一个示例。我们来看看下面的代码:

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 函数调用:

updateUser(user)

这样的单个表达式称为表达式语句(expression statement)

有趣的现象是在纯函数式编程中没有语句。只有表达式

为什么要区分它们?

现在当你理解了什么是表达式语句之后,你会发现当你在图书或者文章中描述代码时是多么的有用。我们一起来看一个例子:

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

在上面的代码片段中,我们可以这样描述 showUsers 是怎样定义的。在它的函数体的第一个语句中,检查 users parameter 是否为 null。注意在 Kotlin 中函数参数是只读的(read-only),这一断言将 users 转换成一个非空值,其函数的剩余代码中它都不会为 null。所以在第二个语句中,我们可以直接使用而不需要做任何解压。注意我们在通过 UserAdapter(it, ::onUserClicked) 表达式将 users 转换成 adapters 时,我们还将 onUserClicked 函数作为参数传递。在最后一个语句中,我们将 list 的 adapter 指定为一个新创建的 UserListAdapter 实例。它包含了为所有 users 创建的 adapters。

注意在描述代码的过程中,语句表达式帮助我们准确的表达想法。

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

注意,在 Kotlin 和 Java 中表述什么是表达式以及什么不是表达式时,两者有基本的差别。所有的 Kotlin 函数调用都是表达式,因为他们至少会返回 Unit。调用没有定义任意返回值的 Java 函数时不是表达式。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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335