Kotlin的两大特性,提高开发效率

0 阅读1分钟

前言

我们来学习两个 Kotlin 的语法特性,从而告别冗长的代码。

字符串内嵌表达式

字符串内嵌表达式(字符串模板)的功能可以让我们不用像 Java 那样使用加号来拼接字符串,而是可以直接将表达式写在字符串里,即使是构建非常复杂的字符串,也变得容易了。

我们先来看个字符串内嵌表达式的例子:

fun main() {
    val name = "snow"
    val hello = "Hello,${name}.You look really good today"
    println(hello)
}

运行结果:

image.png

可以看到我们是在字符串中使用 ${} 这种语法结构来向字符串中嵌入表达式的。

另外,当表达式中只有一个变量时,可以省略大括号:

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")
}

运行结果:

image.png

可以看到 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")
}

运行结果:

image.png

这也是为什么参数默认值可以很大程度上代替次构造函数

比如你看这个例子:

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})")
}

运行结果:

image.png