导读大纲
1.1 基本要素: 函数和变量
- 本节将向你介绍每个 Kotlin 程序都包含的基本元素: 函数和变量
- 你将编写自己的第一个 Kotlin 程序,了解 Kotlin 如何让你省略许多类型声明
- 以及它如何鼓励你尽可能避免使用可变数据–为什么这是件好事
- 你将编写自己的第一个 Kotlin 程序,了解 Kotlin 如何让你省略许多类型声明
1.1.1 编写第一个 Kotlin 程序"你好,世界!"
- Kotlin 中的 “Hello World!”
- 观察到语言语法的一些特征和元素, fun 关键字用于声明函数
- 可以将 main 函数指定为应用程序的顶层入口点,而无需其他参数
- 其他语言可能要求始终接受一个命令行参数数组
- Kotlin 强调简洁: 只需编写 println 就能在控制台中显示文本
- Kotlin 标准库提供许多对标准 Java 库函数的包装
- 语法更加简洁, println(包装System.out.println) 就是其中之一
- 您可以(也应该)省略行尾的分号,就像许多其他现代语言一样
- 观察到语言语法的一些特征和元素, fun 关键字用于声明函数
fun main() {
println("Hello World!")
}
1.1.2 声明带参数和返回值的函数
-
函数声明以 fun 关键字开头,然后是函数名称:本例中为 max
- 之后是括号中的参数列表,在这里,我们声明两个参数,a 和 b,类型都是 Int
-
在 Kotlin 中,首先指定参数名,然后指定类型,中间用冒号隔开
- 返回类型位于参数列表之后, 用冒号隔开
- 返回类型位于参数列表之后, 用冒号隔开
fun max(a: Int, b: Int):Int {
return if (a > b) a else b
}
-
请注意,在 Kotlin 中,if 是一个带有结果值的表达式
- 您可以将 if 视为从其任一分支返回一个值
- 这使得if与其他语言(如 Java)中的三元运算符类似
- 在 Java 中,相同的结构可能看起来像 (a > b) ? a : b
-
然后,您可以使用函数名max调用该函数,并在括号中提供参数
- <1> 每个 Kotlin 程序的入口点都是它的 main 函数(可以不带参数)
- 也可以使用字符串数组作为参数(args:Array)
- 这里数组中的每个元素都对应于传递给App的一个命令行参数
- 也可以使用字符串数组作为参数(args:Array)
- <2> 在任何情况下, main 函数都不会返回任何值
- <1> 每个 Kotlin 程序的入口点都是它的 main 函数(可以不带参数)
fun main() { // <1>
println(max(1, 2))
// 2
}
表达式与语句的区别
-
在 Kotlin 中,if 是表达式,而不是语句
- 表达式和语句的区别在于,表达式有一个值
- 可以作为另一个表达式的一部分使用
- 而语句始终是外层代码块中的顶级元素,没有自己的值
- 表达式和语句的区别在于,表达式有一个值
-
在Kotlin中,除了循环(for、while和do/while)外,大多数控制结构都是表达式
- 这使它有别于 Java 等其他语言
-
具体来说,将控制结构与其他表达式相结合的能力
- 可以让你简洁地表达许多常见的模式
-
下面是一些在 Kotlin 中有效的代码片段
val x = if (myBoolean) 3 else 5
val direction = when (inputString) {
"u" -> UP
"d" -> DOWN
else -> UNKNOWN
}
val number = try {
inputString.toInt()
} catch (nfe: NumberFormatException) {
-1
}
- 另一方面, Kotlin 强制规定赋值必须始终是语句
- 也就是说,在给变量赋值时, 赋值操作本身不会返回值
- 这有助于避免比较和赋值之间的混淆
- 在将比较和赋值视为表达式的语言(如 Java 或 C/C++)中
- 这是错误的常见根源
- 这意味着以下代码不是有效的 Kotlin 代码
- 也就是说,在给变量赋值时, 赋值操作本身不会返回值
val number: Int
val alsoNumber = i = getNumber()
// ERROR: Assignments are not expressions,
// and only expressions are allowed in this context
1.1.3 使用表达式体使函数定义更简洁
-
事实上,可以让 max 函数更加简洁
- 由于函数的主体由一个表达式组成(if (a > b) a else b)
- 因此可以将该表达式作为整个函数的主体,去掉大括号和返回语句
- 取而代之的是,将单个表达式放在等号 (=) 之后
- fun max(a: Int, b: Int):Int = if (a > b) a else b
- 由于函数的主体由一个表达式组成(if (a > b) a else b)
-
如果一个函数的主体是用大括号写的,我们就说这个函数有一个块体
- 如果函数直接返回一个表达式,则它具有表达式体
-
您可以进一步简化 max 函数,省略返回类型
- 乍一看,这可能会让你感到困惑, 怎么会有没有返回类型声明的函数呢?
- 您已经了解到 Kotlin 是一种静态类型语言
- 那么它不是要求每个表达式在编译时都有类型吗?
- 事实上,每个变量和每个表达式都有一个类型
- 每个函数都有一个返回类型
- 但对于表达式体函数,编译器可以分析作为函数体的表达式
- 并将其类型作为函数的返回类型,即使没有明确指定
- 这种分析通常称为类型推断
fun max(a: Int, b: Int) = if (a > b) a else b
- 请注意,只有带表达式主体的函数才允许省略返回类型
- 对于带块体并返回值的函数,必须明确指定返回类型并编写返回语句
- 这是一种有意识的选择
- 现实世界中的函数往往很长,而且包含多个返回语句
- 明确写出返回类型和返回语句有助于快速掌握返回的内容
- 对于带块体并返回值的函数,必须明确指定返回类型并编写返回语句
在 IntelliJ IDEA 和 Android Studio 中转换表达式体和块体
-
IntelliJ IDEA和Android Studio提供在两种函数风格之间进行转换的意向操作
- 转换为表达式体(Expression Body)和转换为块体(Block Body)
-
当光标放在函数或 Alt-Enter(或 macOS 上的 Option-Return)快捷键
- Kotlin 代码中经常会出现带有表达式主体的函数
- Kotlin 代码中经常会出现带有表达式主体的函数
-
你已经看到,当你的函数恰好是一个琐碎的单行
- 打算给条件检查或常用操作起一个好记的名字时,它们就非常方便
- 但当函数评估一个更复杂的表达式(如if、when或try)时,它们也会派上用场