/   今日科技快讯   /

近日,抖音本地生活发布《2022年生活服务软件服务费政策通告》,自6月1日起抖音生活服务将调整软件服务费政策,这意味着抖音将告别“0服务费”的时代。但即便如此,不少商家表示,仍然不会放弃抖音这块流量“肥肉”,还会加大对抖音的投入力度。

/   作者简介   /

明天就是周六啦,大家好好休息,我们下周再见!

本篇文章来自朱涛的投稿,文章分享了对于Kotlin的深度思考,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章。

原文地址:

https://mp.weixin.qq.com/s/24f1ojIUpba0Bvflx2XVsw

/   引言   /

大家好,我是朱涛。

博客两年没怎么更新了,过去的两年里发生了很多事情:

  • 第一,我成为了一名父亲;

  • 第二,郭霖大佬鼓励了我,让我去申请了GDE,很荣幸,我通过了Google的筛选和面试,成为了Kotlin、Android的GDE。(希望疫情赶紧过去,我还欠大佬一顿饭。)

  • 第三,我从上家公司离职,花了半年写了一个技术专栏《Kotlin编程第一课》,体验了一次自由职业者的感觉。

在撰写技术专栏的过程中,我成长了很多,既有技术方面的成长,也有技术之外的成长。

在过去的半年里,我做的最多的事情就是:深度思考。我要想尽一切办法,将自己脑子里的知识掏出来,然后,以最简单、最直观的方式呈现给我的读者。比如说,为了解释清楚Kotlin协程的“挂起和恢复”,我掉了很多头发才找到下面这个灵感:

说实话,我写专栏,根本不是为了钱,单纯就是因为喜欢做这样的事情。这半年里,我写作的态度比从前的工作还拼命;半年里挣的钱,还不如我一个月工资多。但我乐在其中啊,哈哈!

对我来说,读者对课程的赞扬,就是我快乐的源泉。其实,很多互联网的大佬写博客、写书,也是同理。

关于「沉思录」

其实,在这半年里,我还积累了许多创作灵感,这些灵感,大都非常的琐碎,并不足以成为专栏系统课程的一部分。但这些灵感如果不写出来,就太可惜了。所以,我决定将其取名为:「沉思录」,以博客的形式发出来。

「沉思录」,大约分为三个板块:

  • Kotlin沉思录,记录我在Kotlin领域的思考,包括Kotlin JVM,协程,也包括KMM;

  • Android沉思录,记录我在Android、Jetpack领域的思考,两年前我写的《Kotlin Jetpack实战》还是太浅了;

  • Compose沉思录,自然就是Jetpack Compose领域的思考,它的编程理念,实现原理都非常有趣。

今天,我们主要看看Kotlin沉思录。

/   Kotlin 沉思录   /

初学Kotlin的时候,我更多的只是看到了Kotlin的「美」,但经过5年多的沉淀,我也渐渐发现了Kotlin「丑」的一面。

世界上不存在完美的语言,Kotlin也不例外。

其实,一直以来,总有读者问我这样问题:

“Kotlin的最佳实践是什么?”

对于这样的问题,我的回答总是非常的谨慎,说实话,我不敢仅凭我个人的经验就妄下定论。然而,最近,问我这个问题的人越来越多了,有专栏的读者,也有公司的同事。

接下来,我们就来聊聊具体的思路吧,关于Kotlin的「丑」与「美」。

「丑」与「美」

人们常说,穿衣服,要尽量遮住自己「丑」的部位,尽量凸显自己「美」的部分。我的思路也是类似的,简单来说,就是:扬长避短

  • Kotlin的「弱点」

考虑到我GDE的身份,不能大肆宣扬Kotlin的缺点。因此,关于Kotlin「丑」的部分,我会以「弱点」、「坑」为标题。毕竟「丑」与「美」都是非常主观的一种判断,「弱点」则是一种更客观的描述。(没错,我就是比较怂。)

以下是部分主题:

  • 02 | 枚举类的弱点在哪?

  • 03 | Data Class的弱点在哪?

  • 06 | Lambda的弱点在哪?

  • 09 | 扩展函数的弱点在哪?

  • 15 | Channel的弱点在哪?

  • 16 | Flow的弱点在哪?

  • Kotlin之美

聊完Kotlin的「丑」之后,我们就知道Kotlin的「弱点」还有「坑」在哪了,在平时使用的时候,我们就可以很好的避开它的弱点了。

接下来,我们就可以来看看Kotlin的「美」了,欲扬先抑嘛。

以下是部分主题:

  • 17 | 如何理解Kotlin语法之美?

  • 18 | 如何理解sealed之美?

  • 21 | 如何理解Delegation之美?

  • 23 | 如何理解协程之美?

  • 26 | 如何理解Flow之美?

  • 30 | 如何理解inline之美?

Kotlin的「最佳实践」到底是什么?看完上面的这些系列以后,我相信每个读者都会有一个自己的答案吧!

Kotlin其实是一个非常宽泛的话题,除了语法特性层面的「丑」与「美」,其实还有许多能聊的东西,比如:编程范式、DSL设计、数据结构与算法、设计模式,KMM、Compose Multiplatform。这些内容,我都会尝试在这个系列的博客里去做一些涉猎。

关于深度

沉思录这个系列不是面向0基础读者的,这里主要会记录我平时的一些灵感和思考,它更像是不成体系的Android、Kotlin随笔。如果你是有一定经验的开发者,应该能让你有所启发。(不敢保证哈。)

如果你对Kotlin没有一个全面的认识,那我建议你先去看看Kotlin官方文档。如果你觉得官方文档枯燥乏味,也可以去看看我公众号里的历史文章,我自认为讲的还不错。

OK,闲聊结束,我们进入正题。

/   「又爱又恨」的特性   /

我们都知道,Kotlin会为成员属性自动生成getter、setter。不论是使用var、还是使用val,Kotlin编译器都会自动帮我们处理getter、setter的问题。

// 代码段1class GetterSetterDeepDive {// varvar name: String = "朱涛的自习室"// valval desc: String = "Kotlin, Android and more."
}

如果将上面的Kotlin代码反编译成Java的话,它大致会长这样:

// 代码段2public final class GetterSetterDeepDive {private String name = "朱涛的自习室";private final String desc = "Kotlin, Android and more.";public final String getName() {return this.name;}public final void setName(String var1) {this.name = var1;}public final String getDesc() {return this.desc;}
}

在我初学Kotlin的时候,我曾对着这个案例感叹:Kotlin 666!一行顶十行啊!用Kotlin开发,果然能大大提升效率啊!

说实话,现在回过头来看,当时的我就跟个“脑残粉”一样,大家不要学我。

好了,言归正传,有一说一,Kotlin自动生成getter、setter,它这样的行为,对比Java确实是一大进步,因为它可以避免外部的类直接访问Kotlin类当中的字段(Field)。毕竟,我们都知道,类似下面这样的Java代码是非常不合理的。

// 代码段3public class FieldJavaBean {public String name = "朱涛的自习室";public final String desc = "Kotlin, Android and more.";
}

上面的代码,既不符合开放封闭的原则,也难以维护。对比之下,Kotlin生成的代码段2的代码,则要顺眼很多。然而,Kotlin这样的策略其实也有它丑陋的一面。让我们来看看下面的例子。

Getter、Setter的第一个弱点

Kotlin的Getter、Setter主要有两个弱点,我们先来看它的第一个弱点,请看下面的代码。

// 代码段4class GetterSetterDeepDive {var name: String = "朱涛的自习室"val desc: String = "Kotlin, Android and more."fun printName() {println("name = $name,desc = $desc")}
}

请问,这段代码的问题在哪?抛开当前文章的语境,如果你是在面试当中遇到这样一个问题,你会给出怎样的答案?

你可以停下来思考一下,心里有了答案以后再继续往后看。

Kotlin最大的问题就在于,大部分的开发者很难意识到Kotlin编译器背后自动生成的那些getter、setter方法,从而导致这个特性被滥用。

让我们将上面的代码反编译来看看。

// 代码段5public final class GetterSetterDeepDive {private String name = "朱涛的自习室";private final String desc = "Kotlin, Android and more.";// 1public final String getName() {return this.name;}// 2public final void setName(@NotNull String var1) {this.name = var1;}// 3public final String getDesc() {return this.desc;}public final void printName() {// 并不会用到getter、setterString var1 = "name = " + this.name + ",desc = " + this.desc;System.out.println(var1);}
}

可以看到,注释1、2、3对应的这三个自动生成的getter、setter方法,它们根本就没被用到!这样的问题,如果是在一个非常小的规模,其实是无伤大雅的,但对于一个大的工程来说,当这样的问题积少成多,就会极大增加方法数,还有应用的包体积。这一点对Android应用尤为重要。

那么,以上的问题该怎么解决呢?答案其实也很简单:

// 代码段6class GetterSetterDeepDive {
// 变化在这里
//     ↓private var name: String = "朱涛的自习室"private val desc: String = "Kotlin, Android and more."fun printName() {println("name = $name,desc = $desc")}
}

我们将其反编译成Java看看:

// 代码段7public final class GetterSetterDeepDive {private String name = "朱涛的自习室";private final String desc = "Kotlin, Android and more.";public final void printName() {String var1 = "name = " + this.name + ",desc = " + this.desc;System.out.println(var1);}
}

这样的 Java 代码看起来是不是干净了很多?这就对了!

反思

Kotlin编译器自动生成Getter、Setter的操作,它对比Java确实是存在优势的,因为它更符合「开放封闭」的原则。我们Kotlin开发者随手写出的var、val,它背后都会转换成Java当中的「最佳实践」,真的很方便。这个设计最精彩的地方在于:「简洁」,简单的var背后代表了:Field + Getter + Setter,这样的信息密度是Java所不能比拟的。不得不佩服Kotlin设计者的精妙构思。

然而,几乎所有的技术都是一种trade-off,Kotlin这样「方便」、「简洁」的设计,让它丢失了许多底层的信息。许多开发者只看到了var的方便,却很容易忽略它底层自动生成的Field + Getter + Setter。Kotlin官方其实也在想办法解决类似这样的问题,但这远远不够。

当我们写出有问题的代码时,IDE其实是会有警告的。可是,它只告诉了我们:desc可以变成private,并没有告诉我们具体的后果。当我们看到这样的提示时,我们脑子里很难将“private”与“Getter、Setter”建立对等的关系。

  • 对于var属性来说,加上private修饰,就意味着方法数减2;

  • 对于val属性来说,加上private修饰,就意味着方法数减1;

其实,许多事物发展到一定程度,最后都会开始拼细节。考试是如此、商业是如此、编程也是如此。

好,考虑到篇幅限制,我们之后再聊Getter、Setter的第二个弱点吧!我们下期再见!

推荐阅读:

我的新书,《第一行代码 第3版》已出版!

我为Android版Microsoft Edge所带来的变化

Android蓝牙开发攻略,就是这么easy!

欢迎关注我的公众号

学习技术或投稿

长按上图,识别图中二维码即可关注

沉思录| Kotlin的「丑与美」,以及「最佳实践」相关推荐

  1. 「ReactNaitve」对hooks最佳实践的探索

    author: 轩邈 一.hooks介绍 一. useState eg: const [count, setCount] = useState(0) 介绍 (1)有一个参数:默认值, 可以是函数,只在 ...

  2. lvm 多个硬盘合成一个_「ECS最佳实践」基于多块云盘构建LVM逻辑卷

    一.LVM简介 LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管 ...

  3. 左手沉思录道德情操论右手

    内容简介: <左手沉思录道德情操论右手>是英国经济学家和伦理学家亚当·斯密的传世经典著作之一.在该书中,亚当·斯密用同情的基本原理来阐释正义.仁慈以及克己等一切道德情操产生的根源,说明了道 ...

  4. 马可奥勒留《沉思录》读后感作文6000字

    马可奥勒留<沉思录>读后感作文6000字: 马可奥勒留的<沉思录>早有耳闻,一直没有去读是因为还没有碰到靠自己的之前的思考模式解决不了的难题.但近一年多来的迷茫让我认识到在执行 ...

  5. 读书笔记∣概率论沉思录 01

    概率的解释基础分为两种,一是物理世界本身存在的随机性(客观概率),二是是我们由于信息不足而对事件发生可能性的度量(主观概率).基于此,形成了概率论的两大学派:频率论学派(传统数理统计学)和贝叶斯统计学 ...

  6. 《设计模式沉思录》—第2章2.4节访问权限

    本节书摘来自异步社区<设计模式沉思录>一书中的第2章,第2.4节访问权限,作者[美]John Vlissides,更多章节内容可以访问云栖社区"异步社区"公众号查看. ...

  7. 产品沉思录精选:为何知识资本将胜过金融资本

    <明朝那些事儿>中,有一个章节专门是讲王阳明如何找到「知行合一」这个重要的方法论的 -- 在此之前,他遵循先辈的理学,不停地「格物」但却最终没有见到什么效果,因为有「知识」的人并不注重行动 ...

  8. 一切笔直都是骗人的 —— 2020 年产品沉思录卷首语摘录

    小时候很喜欢看<读者>,尤其是其中的「言论」部分,在那个能把所有书籍读完的时代,很难走出家门五公里的年代,这些字字玑珠的文字仿佛打开了另外一个世界的大门. 抽空把 2020 年产品沉思录的 ...

  9. 产品沉思录精选:如何管理需求优先级 | RICE方法

    虎年的第一期产品沉思录精选,是去年看到很想推荐的关于如何判断需求优先级的方法论.这是一种理念上的变化,但是可能落地到工作实践中会有些难度.没关系,在新的一年知道了还存在另一种经过认真思考的方法也是不错 ...

最新文章

  1. linux怎么调整运行模式,如何手动设置修改X-Window的显示模式-linux思想
  2. CodeForces - 468C Hack it!(构造+数位dp)
  3. VMware中虚拟机与主机不能ping通解决办法
  4. linux基础命令(-)
  5. android开发板功能,Android中NFC模块PN532开发板应用/原理图/PCB等全部资料
  6. java操作oracle数据_Java jdbc操作oracle数据库的两种方式
  7. springboot yml对于list列表配置方式
  8. C++ 数据类型转换详解之终极无惑
  9. 数据结构中的头结点和头指针
  10. scratch教程2-程序sb,sb2,sb3转换EXE,HTML
  11. 【软考】系统集成项目管理工程师(八)项目进度管理
  12. 如何注册域名邮箱?个人域名邮箱怎么弄?域名邮箱登录入口?
  13. 雅诗兰黛公司宣布线上业务部门领导层更新
  14. 【笔记整理】vue.js笔记
  15. Kafka基于Zookeeper搭建高可用集群实战
  16. 2. 测试分析与测试设计
  17. androidtv gms包_Android之GMS自我总结
  18. STM32 标准外设库(Standard Peripheral Library)
  19. 【转帖】大数据时代的文化与版权
  20. 数据库SQL Server基本认识

热门文章

  1. iOS 根据颜色生成图片
  2. Parquet encoding
  3. 现在,中国的互联网公司该不该走出国门?
  4. 读俞敏洪老师的文章--坚持下去.[他给了我勇气]
  5. 掘金量化—Python SDK文档—5.API 介绍(2)
  6. Springboot 自定义注解、切面
  7. Jenkins Pipeline checkout scm拉取代码
  8. 无线手柄发送接收间断的问题
  9. [嵌入式] 重温Mini2440(一)移植U-Boot
  10. 新冠感染发病过程记录