加餐三 | 什么是“不变性思维”?
朱涛
你好,我是朱涛。
在开篇词里,我提到过学习 Kotlin 的五种思维转变,包括前面加餐中讲过的函数思维、表达式思维,以及接下来要给你介绍的不变性思维、空安全思维以及协程思维。所以今天,我们就一起来聊聊 Kotlin 的不变性思维。
Kotlin 将不变性的思想发挥到了极致,并将其融入到了语法当中。当开发者想要定义一个变量的时候,必须明确规定这个变量是可变的(var),还是不可变的(val)。在定义集合变量的时候,也同样需要明确规定这个集合是可变的(比如 MutableList),还是不可变的(比如 List)。
不过,不变性其实会被很多 Kotlin 初学者所忽略。尤其是有 Java、C 经验的开发者,很容易将老一套思想照搬到 Kotlin 当中来,为了方便,写出来的变量全部都是 var 的,写出来的集合都是 MutableXXX。
事实上,不变性思维,对我们写出优雅且稳定的 Kotlin 代码很关键。要知道,我们代码中很多的 Bug 都是因为某个变量被多个调用方改来改去,最后导致状态错误才出问题的。毕竟,变动越多,就越容易出错!
那么,既然可变性这么“可恶”,我们为何不干脆直接在语法层面消灭 var、MutableXXX 这样的概念呢?
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
Kotlin的不变性思维是编程中的重要思维方式,旨在消灭可变性,提高代码稳定性和可靠性。文章从消灭var、MutableXXX、使用条件表达式、数据类等角度出发,强调了不变性思维的重要性。同时,对集合的不变性也进行了深入讨论,强调了只读集合的重要性以及val的灵活性。通过具体的代码案例,全面介绍了Kotlin的不变性思维,对于想要深入了解Kotlin编程的开发者具有重要的参考价值。文章内容深入浅出,适合技术人员快速了解Kotlin的不变性思维。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(13)
- 最新
- 精选
- BUG君使用copy()方法, 每次都会创建一个新的对象, 如果不注意在for循环里面使用该方法, 很可能会造成内存抖动
作者回复: 是的。
2022-05-2315 - 魏全运kotlin 的函数式不变性思维也有一些不好的地方,比如对集合使用各种内置操作符链式调用时,每个操作都会new一个新的拷贝,这时候可以把集合在开始时转成sequence 来操作,避免构造太多中间变量。当然,这也不是万能的,sequence 是一个迭代器,不能覆盖所有场景
作者回复: 说的很好,感谢这位同学的补充! Kotlin不变性思维有利也有弊,在有些高性能场景下,我们要进行取舍。
2022-02-0826 - Paul Shan尽量避免写操作,不得不写的时候,优先考虑拷贝返回,最后才是提供读写操作。读写操作最直观,但是太容易到处写,最后很可能导致全局变量一样的毛病,不知道哪里修改了状态,如果有多线程并发的情况下,更加难调试。
作者回复: 是的。
2022-03-205 - Geek_66aa0cSingletonList是java.util.Collections类的内部类,只保存一个元素,在初始化需要赋值,如: List<String> list = Collections.singletonList("ok"); 并且不支持add、remove方法
作者回复: 可以看看这位同学的补充。
2022-02-154 - 爱学习的小羊老师好,如果一个APP,需要有修改用户信息的功能,比如修改了用户信息里的身高,这个用数据类怎么处理呀
作者回复: 可以这样:Copy一下创建新的对象,然后用新的对象更新UI,这时候可能需要考虑Diff。
2022-03-213 - 白乾涛关于Java中的不变性集合,为什么我自动导了 java.util.List 而不是 SingletonList? 而且我报的错是 ClassCastException: java.lang.String cannot be cast to java.lang.Void ? import java.util.List; class Test { public static void main(String[] args) { List<String> data = new Model().getData(); data.add("bqt"); // ClassCastException: java.lang.String cannot be cast to java.lang.Void } }
作者回复: 是有这个可能的,Kotlin底层编译器的转换规则是不透明的。 不过,你可以运行时打断点看看,反编译的类型不一定就是运行时的,因为SingletonList也算是List的子类。
2022-02-192 - A Lonely Cat我对 val 不可变理解是:地址不变(在 kotlin 下无法二次赋值,类似Java中的 final 关键字修饰的属性),但是值可能会变(通过该对象的相关方法修改属性)
作者回复: 总结很到位。
2022-02-082 - better加餐的内容,非常不错。
作者回复: 加油哈~
2022-02-072 - 墨方数据类用copy做更改,太麻烦了吧,难道没有更好的方式了吗?
作者回复: 如果你追求“不变性”,那么数据类的copy就是最方便的选择了。否则你就得var来实现了,这其实是一种取舍。
2022-02-0721 - 山河入梦想请教一下老师,对于数据类用val声明的字段如果后台返回了null怎么办,尤其是“陈年接口”
作者回复: 目前我的做法是:使用Moshi进行JSON解析,再搭配一些自定义的配置。由于文字解释起来比较复杂,具体方案,我会在Android项目篇的时候详细介绍的,请留意。
2022-03-032
收起评论