【码上开学】Kotlin 的变量、函数和类型

本文介绍了 Kotlin 语言的关键特性,包括空安全设计、延迟初始化、类型推断、val 和 var 的区别,以及函数声明和可见性。Kotlin 的空安全设计通过编译时检查避免了运行时的 NullPointerException。延迟初始化变量 `lateinit` 用于那些无法在声明时初始化但确保后续会初始化的情况。类型推断简化了代码,而 val 和 var 分别对应只读和可读写变量。此外,文章还讨论了函数声明和可见性,包括 getter 和 setter 函数的使用。
摘要由CSDN通过智能技术生成

我们回忆下 Java 里声明一个 View 类型的变量的写法:

☕️
View v;

Kotlin 里声明一个变量的格式是这样的:

🏝️
var v: View

这里有几处不同:

  • 有一个 var 关键字
  • 类型和变量名位置互换了
  • 中间是用冒号分隔的
  • 结尾没有分号(对,Kotlin 里面不需要分号)

看上去只是语法格式有些不同,但如果真这么写,IDE 会报错:

🏝️
class Sample {
var v: View
// 👆这样写 IDE 会报如下错误
// Property must be initialized or be abstract
}

这个提示是在说,属性需要在声明的同时初始化,除非你把它声明成抽象的。

  • 那什么是属性呢?这里我们可以简单类比 Java 的 field 来理解 Kotlin 的 Property,虽然它们其实有些不一样,Kotlin 的 Property 功能会多些。

  • 变量居然还能声明成抽象的?嗯,这是 Kotlin 的功能,不过这里先不理它,后面会讲到。

属性为什么要求初始化呢?因为 Kotlin 的变量是没有默认值的,这点不像 Java,Java 的 field 有默认值:

☕️
String name; // 👈默认值是 null
int count; // 👈默认值是 0

但这些 Kotlin 是没有的。不过其实,Java 也只是 field 有默认值,局部变量也是没有默认值的,如果不给它初始值也会报错:

☕️
void run() {
int count;
count++;
// 👆IDE 报错,Variable ‘count’ might not have been initialized
}

既然这样,那我们就给它一个默认值 null 吧,遗憾的是你会发现仍然报错。

🏝️
class Sample {
var v: View = null
// 👆这样写 IDE 仍然会报错,Null can not be a value of a non-null type View
}

又不行,IDE 告诉我需要赋一个非空的值给它才行,怎么办?Java 的那套不管用了。

其实这都是 Kotlin 的空安全设计相关的内容。很多人尝试上手 Kotlin 之后快速放弃,就是因为搞不明白它的空安全设计,导致代码各种拒绝编译,最终只能放弃。所以咱先别急,我先来给你讲一下 Kotlin 的空安全设计。

Kotlin 的空安全设计

简单来说就是通过 IDE 的提示来避免调用 null 对象,从而避免 NullPointerException。其实在 androidx 里就有支持的,用一个注解就可以标记变量是否可能为空,然后 IDE 会帮助检测和提示,我们来看下面这段 Java 代码:

☕️
@NonNull
View view = null;
// 👆IDE 会提示警告,‘null’ is assigned to a variable that is annotated with @NotNull

而到了 Kotlin 这里,就有了语言级别的默认支持,而且提示的级别从 warning 变成了 error(拒绝编译):

🏝️
var view: View = null
// 👆IDE 会提示错误,Null can not be a value of a non-null type View

在 Kotlin 里面,所有的变量默认都是不允许为空的,如果你给它赋值 null,就会报错,像上面那样。

这种有点强硬的要求,其实是很合理的:既然你声明了一个变量,就是要使用它对吧?那你把它赋值为 null 干嘛?要尽量让它有可用的值啊。Java 在这方面很宽松,我们成了习惯,但 Kotlin 更强的限制其实在你熟悉了之后,是会减少很多运行时的问题的。

不过,还是有些场景,变量的值真的无法保证空与否,比如你要从服务器取一个 JSON 数据,并把它解析成一个 User 对象:

🏝️
class User {
var name: String = null // 👈这样写会报错,但该变量无法保证空与否
}

这个时候,空值就是有意义的。对于这些可以为空值的变量,你可以在类型右边加一个 ? 号,解除它的非空限制:

🏝️
class User {
var name: String? = null
}

加了问号之后,一个 Kotlin 变量就像 Java 变量一样没有非空的限制,自由自在了。

你除了在初始化的时候可以给它赋值为空值,在代码里的任何地方也都可以:

🏝️
var name: String? = “Mike”

name = null // 👈原来不是空值,赋值为空值

这种类型之后加 ? 的写法,在 Kotlin 里叫可空类型

不过,当我们使用了可空类型的变量后,会有新的问题:

由于对空引用的调用会导致空指针异常,所以 Kotlin 在可空变量直接调用的时候 IDE 会报错:

🏝️
var view: View? = null
view.setBackgroundColor(Color.RED)
// 👆这样写会报错,Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type View?

「可能为空」的变量,Kotlin 不允许用。那怎么办?我们尝试用之前检查一下,但似乎 IDE 不接受这种做法:

🏝️
if (view != null) {
view.setBackgroundColor(Color.RED)
// 👆这样写会报错,Smart cast to ‘View’ is impossible, because ‘view’ is

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值