看 码上开学 的视频记录。
1. 变量
如果你在写变量的时候是这样的 val name ,那么很抱歉,会报错的,因为 kotlin 没有默认值一说,刚开始的时候我也很郁闷,但是我看到 NullPointerException 的时候好像明白了。就像扔物线所说的那样,既然声明了就是要用的。
val name: String = "wujingyue"
这样就可以了,但是有时候我们就是不想初始化,准确的说是还不知道值,不知道初始化啥,就这个问题,我比较喜欢的是要么指定一个默认值,那么加上关键词 lateinit,就像这样:
lateinit var name: String
println(name)
这样在 ide 中不报错了,但是运行会报错 Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property name has not been initialized at MainKt.main(main.kt:5) 。扔物线说 lateinit 只不过是告诉编译器不检查这个变量有没有初始化了,根据这个现象我觉得非常合理。还有一种情况是指定为 null ,如果直接指定也是会报错的。
直接指定会出现错误
根据上面的提示修改即可:
val name: String? = null ,这样的话直接打印 name 是 null ,并不会像上面那样出现报错。让我们来想想这个世界,你可能会买杯子,买回来的时候是空的,如果你在没有装水或其他液体的时候使用了它,你用的时候发现没有,到不出现。假如说你要喝水,原本你就没有装水,你喝水的时候就会发现没有水,此时喝水这件事情就没法做下去,只能搁置,或者去装完水再喝。
一般都会检查,如果发现没有就没必要做下面的工作;即便你用了也没关系,因为你啥也得不到,但这是不可取的。比如有一个过程是需要将电压降低到
38V ,结果前一个过程没有做,或者在你之前有人又升上去了,此时如果你接着操作就会触电而死。这就说明如果想保证“你喝水的时候一定有水喝”,那么就需要保证“给杯子装水”这一步就一定要进行,但人有时候会忘,即便记住了,有可能装满以后仍然有其他人将其倒掉或者一些不好的操作。
所以在做操作之前,做一下检查是非常有必要的。
所以
kotlin 做了这个操作是有必要的,写业务逻辑的时候也是有必要的:
fun main(args: Array<String>) {
val name: String? = null
println(name?.toUpperCase())
}
// 输出: null
相比于 lateinit ,我更倾向于 ? 的方式,这样的话在使用的时候就会向上面那样访问了。上面说的逻辑检查是指在你做相关逻辑之前看看你所需要的数据是不是符合你对数据的要求,比如说选美,参加的女性必须在 18-25 岁之间的,但是经过初步筛选以后不一定都是达标的,此时就需要进行检查,看看传进来的数据是不是这个区间的,不是的就剔除掉。这里只是随便举的一个例子。
2. object 和 companion object
单例模式实现起来很麻烦,但是在 kotlin 中就不一样了,只需要这样:
object test {
var name = "wujingyue"
var age = 25
}
fun main(args: Array<String>) {
println(test.name)
println(test.age)
}
这里的 object 就是声明一个对象,就像 js 里面的 let obj = {} 一样。然后就可以直接使用了,就像里面的全是静态属性或静态方法一样。
那 kotlin 里面怎么做到即有静态属性或方法,使用 companion object 就可以了。
class Test {
var isAction = true
companion object {
var name = "wujingyue"
var age = 25
}
}
fun main(args: Array<String>) {
println(Test.age)
println(Test.name)
val test = Test()
println(test.isAction)
}
在 companion object 里面的都是静态属性或方法。









网友评论