前言
我们来学习两个 Kotlin 的语法特性,从而告别冗长的代码。
字符串内嵌表达式
字符串内嵌表达式(字符串模板)的功能可以让我们不用像 Java 那样使用加号来拼接字符串,而是可以直接将表达式写在字符串里,即使是构建非常复杂的字符串,也变得容易了。
我们先来看个字符串内嵌表达式的例子:
fun main() {
val name = "snow"
val hello = "Hello,${name}.You look really good today"
println(hello)
}
运行结果:
可以看到我们是在字符串中使用 ${}
这种语法结构来向字符串中嵌入表达式的。
另外,当表达式中只有一个变量时,可以省略大括号:
val hello = "Hello,$name.You look really good today"
为什么这样会更方便?
这就不得不提起 Java 拼接字符串的写法了,例如:
public static void main(String[] args) {
String name = "Snow";
int age = 21;
System.out.println("Person(name=" + name + ", age=" + age + ")");
}
当需要拼接的变量一多,代码的可读性就会变得很差。而且这种写法,不仅麻烦,还容易写错。
而字符串内嵌表达式就简单多了,可读性还高:
fun main() {
val name = "Snow"
val age = 21
println("Person(name=$name, age=$age)")
}
字符串内嵌表达式(字符串模板)可以让我们一眼就看出最终字符串的结构,特别对于构建复杂的动态字符串来说(如SQL查询语句),简直是至宝。
函数的参数默认值
这个功能可以让我们给函数的某个参数设定一个默认值。这样,在调用此函数时,如果没给这个参数传递值,Kotlin 会自动使用它的默认值。
我们来看个例子:
fun hello(name: String, message: String = "Hello!") {
println("$message, $name")
}
在这个例子中,我们给 message
参数设定了默认值,调用 hello()
函数时,可以省略 message
参数,不给 message
参数提供值:
fun main() {
hello("Jack")
}
运行结果:
可以看到 message
参数自动使用了我们设定的默认值 "Hello!"
。
那问题来了,如果带默认值的参数在前面怎么办?
我们修改例子,变为给第一个参数设定默认值:
fun hello(name: String = "Martin", message: String) {
println("$message, $name")
}
如果想让 name
参数使用默认值,使用之前的写法,会给第一个参数也就是 name
参数传值,导致没有给 message
参数传递任何值。
fun main() {
hello("NiHao") // 报错:No value passed for parameter 'message'
}
这时,可以使用 Kotlin 的键值对传值的方式(具名参数)来传参,通过参数名指定我们的值要传给哪个参数,而不需要按照参数的顺序依次传参。
就刚刚的问题,我们可以这样做:
fun main() {
hello(message = "NiHao")
}
运行结果:
这也是为什么参数默认值可以很大程度上代替次构造函数。
比如你看这个例子:
class Account(val username: String, val password: String, val email: String) {
constructor(username: String, email: String) : this(username, "123456", email) {
}
constructor(username: String) : this(username, "$username@xx.com") {
}
}
上述例子中,次构造函数的作用是以更少的参数来创建一个 Account
账户对象。
但这种写法在 Kotlin 中是不必要的,我们可以只编写一个主构造函数,然后给函数中的参数设定默认值,也能实现上述效果:
class Account(
val username: String,
val password: String = "123456",
val email: String = "$username@xx.com",
) {
}
我们可以测试一下,使用任意方式对 Account
类进行实例化:
fun main() {
// 只提供 username 参数
val a1 = Account("Johnson")
println("Account(username=${a1.username}, password=${a1.password}, email=${a1.email})")
// 提供 username 和 email 参数
val a2 = Account("Mary", "mary.chen@corp.com")
println("Account(username=${a2.username}, password=${a2.password}, email=${a2.email})")
// 全参数
val a3 = Account("David", "david@gov.tw", "a_strong_password")
println("Account(username=${a3.username}, password=${a3.password}, email=${a3.email})")
}
运行结果: