如何看待Kotlin和Lombok

借用李宗盛的一句歌词:

  • 女:为何你不懂

  • 男:别说我不懂

  • 女:只要有爱就有痛

  • 男:有爱就有痛

  • 女:有一天你会知道,人生没有我并不会不同

  • 男:没有你会不同


我个人的背景和基本立场:

1、十余年的程序员,极客,用过二十多门编程语言,终身学习者。

2、轮子大王,喜欢微创新,众多开源项目作者和参与者。

3、项目开发经理、技术经理、公司级架构师,主抓工程效率、质量和可维护性。


Lombok和Kotlin实际上都是“语法糖”,既然是糖,当然有甜头,语法层面(本文只做简单点评),我认为大部分语法改进是好的,但是像Kotlin移除了原生static变量和方法,改用伴生对象(companion object),这种做法有些激进。


实际上,任何语法都是一把“双刃剑”,语法不是越多越好,也不是越简单越好,比如@Data、@RequiredArgsConstructor这种大家觉得很常用的功能,为什么Java语言不直接官方支持,如果你是编程语言的作者,你会怎么考虑?一门大众语言,要考虑易学、易用、通用、兼容性、受众面以及底层大家看不到的东西(跨平台、性能、复杂度、破坏性、可维护性)剑走偏锋,不是一门成熟语言的性格。在我的另一篇文章《浅论各种编程语言》中有更为详细的说明。


在此,我只强调两点:


一、语法必须要考虑的基本问题

1、易用:大部分语法的第一设计原则就是让原本很难实现的编程,用更简单的方式来实现。

2、受众多寡:针对一个很小众的功能,通常不会从语法层面去改进它的易用性。

3、通用性:针对99.99%甚至100%的相似用例和场景,都应该有相同的语法,且不需要额外配置,否则会降低易用性。

4、统一性:针对相似用例和场景,通常的写法只有一种(最多可接受两种),不存在两种以上功能重叠的语法。

5、易学:语法概念简单、直观,一看就懂,语法通用性、统一性好,不存在针对不同情况的各种变异用法或配置。判断标准:一个语法的教程一段话就能说完,语法的变种或配置不超过两个。


像lombok、kotlin这样的语法,在Java这种成熟语言的基础上做文章,盯上的主要是上面的第1、2点进行扩展,在一些受众比较大的、使用频繁的地方,做一些更易用的语法。但是它们在第3、4、5项上,做得就不如原生Java语言那样周全。

举几个例子,例如:

@ToString(onlyExplicitlyIncluded=true, includeFieldNames=true, callSuper=true)
@Data(staticConstructor = "of")
public class Point { final int x, y; }

@Builder(toBuilder=true)
@AllArgsConstructor(onConstructor=@__({@Annotations}))
@NoArgsConstructor
public class Point { final int x, y; }

为什么lombok要支持多种配置?还不是因为它想支持更多的功能,它想做得更通用、更统一、更强大。但是一旦它变得更强大,支持了丰富的配置和更多的语法,它的易用性、易学习性、易维护性甚至兼容性就会降低。一个200行的Java程序,我们完全可以通过类似lombok这种方式,把代码精简到100行,甚至更狠,精简到10行!但是我们怎么做到同时兼顾上面所说的那5个语法基本要求:受众广、通用性高、统一性高、易学易用?


还有一个灵魂拷问:即便是你觉得这个语法糖很好,你觉得简单、直观、不复杂,你认为上面那5个要求全都满足,但是你认为你的同事(包括初级的程序员)和将来入职的新同事,都能直接上手维护你的代码吗?如果他们做不到,那你认为是什么原因呢?


二、语法是否能融入、兼容已有的广大生态


比如,Java语言,有编辑器的代码“语法高亮”插件,有Eclipse、IdeaJ等成熟的开发工具(支持热编译、Debug),有Checkstyle、FindBugs、PMD等代码扫描工具,甚至还有很多直接生成Java代码、生成UML类图等生态工具。那么,一旦你把Java代码换成了Kotlin、Lombok代码之后,上述的那些工具还能用吗、会不会有很大的坑?


这么说吧,Kotlin都发布10年了,至今它的生态都不太完善。Android是官方支持它的,然而还是会有不完善的地方。


举个例子,在Android Studio中,编写如下Java代码:

public class Test {

    public static void main(String[] args) {
        System.out.println(KotlinClass.STATIC_VAR);
        System.out.println(JavaClass.STATIC_VAR);
    }
}

其中 KotlinClass.kt 是 kotlin格式代码,JavaClass.java 是 java格式代码。

如果修改了 JavaClass.STATIC_VAR 这个变量的定义,编译器就能实时地识别到引用关系,提示报错。

但是修改了 KotlinClass.STATIC_VAR这个变量的定义,编译器就不会实时识别到引用关系,不会提示报错。

大家都知道,写代码时,如果没有报错提醒,直到手动编译时才知道报错,那种体验会有多糟糕。


想一想,要放弃一个成熟的生态,去拥抱一个不成熟的生态,需要多勇敢。很多语言刚出来那时候,甚至连打断点调试的功能都没有,代码检查和语法高亮功能也没有,个人小项目无所谓,复杂的项目以及多人协作的项目,可能就需要更成熟的考虑。


顺便

说一下我看好的几门语言:

  • Java(企业级应用NO.1)

  • C(底层软件)

  • HTML、CSS(网页霸主)

  • TypeScript(新一代JS)

  • Python(易学易用的万金油)

  • Golang(新宠,介于C和Java之间,国内外大厂支持,已成气候)

  • C++等

咱们拭目以待!


© 2009-2020 Zollty.com 版权所有。渝ICP备20008982号