1

深入使用 Kotlin 后的感受

之前写过一篇对于 kotlin 较为粗略的感受,简单的描述了一下 kotlin 的几个优点,例如对空对象的判断等。

在经过一段时间对 kotlin 的探索后,我发现这些优点远不是 kotlin 的全部,于是再深入的写一篇关于 kotlin 的使用感受。

最近一个项目,开始全面的使用 kotlin 这门语言,也有了更多的机会去体验 kotlin 的新特性。

大量使用 kotlin 的感受就是,每当在设计一个问题的解决方案时,你突发的独特灵感都能够被 kotlin 满足,能极大的提高你的编程体验,这是之前使用任何语言都未成有过的感受。

能够被设计的代码

kotlin 的使用,让我觉得自己不是被语言所操控的,你自己就能够操控语言本身。

当你需要设计自己的工具时,kotlin 对你的帮助是巨大的,它能让你随时随地创造出来一种好用的独特的,又不会让你觉得突兀的工具。

例如,当你厌倦了下面这种写法时

val isError = true
if (isError) {
        throw Exception("")
}

你可以

fun Boolean.ifThr(message: String) {
    if (this) {
        throw Exception(message)
    }
}

val isError = true

isError.isThr("")

从此你就拥有了一个直接通过 Boolean 对象抛出异常的工具。

或许你还想在抛出异常时,打印一个日志。

fun Boolean.ifThr(message: String, func: (() -> Unit)? = null) {
    if (this) {
        func?.let { it() }
        throw Exception(message)
    }
}
val isError = true

isError.isThr("") // 不打印日志,直接抛出
isError.isThr("") { // 打印日志,并抛出
        log.error("")
} 

你甚至可以让 Boolean 值为空的时候,能够不加判断的执行抛出异常。

fun Boolean?.ifThr(message: String, func: (() -> Unit)? = null) {
    if (this == true) {
        func?.let { it() }
        throw Exception(message)
    }
}
val isError :Boolean? = null
isError.ifThr("")

也可以扩展 List 的方法,判断一组结果是否全为 true。

fun List<Boolean>.allTrue(): Boolean {
    this.forEach {
        if (!it) {
            return false
        }
    }
    return true
}

上面一个方法展示了好几种特性,他们单个使用或许威力不大,但当组合起来时,你会惊讶于它的表现力、便捷性之强,能够让你的代码在大量减少的同时,兼顾到可读性、优雅实现、实用性的结合。

这就是 kotlin 强大的地方,如果你愿意,你可以先优雅的设计,再优雅的编码。

当然,优雅只是一个副产物,它真正的作用是。

让你以一种低成本的方式,设计出一种编码模式,能够帮你更好的处理掉业务需求实现的细节,从而专注于业务需求的实现,大量减少逻辑错误的发生,同时显著降低纠错成本。

编码过程不再被打断

你可能遇到过这样一种情况(以 elasticsearch 为例)

val searchRequestBuilder = SearchRequest.Builder()
            .source {
                it.filter { it.includes("id") }
            }
            .index(modelIndexNames)
            .query(query)
            .sort {
                it.field(FieldSort.Builder().field("id").build())
            }
            .size(10000)
        sort?.let { searchRequestBuilder.searchAfter(it) }
        searchRequestBuilder.build()

你可以看到,原本 SearchRequest 的设计思路是使用过程连续不中断的,但是一旦碰到中间需要判断的地方,就不得不打断这一过程,虽然不影响整体功能,但可读性稍差一些。

可以优化成下面的写法

val searchRequest = SearchRequest.Builder()
            .source {
                it.filter { it.includes("id") }
            }
            .index(modelIndexNames)
            .query(query)
            .sort {
                it.field(FieldSort.Builder().field("id").build())
            }
            .apply {
                sort?.let { searchAfter(it) }
            }
            .size(10000)
            .build()

这样,一段在 java 中必然会被打断的代码,在 kotlin 中能够被流畅的写出来。

使用过程中的疑虑

在我看来,kotlin 浑身都是优点。

但是随着我对 kotlin 理解和写法上的深入,我开始逐渐担心起来。

每当我写了一些 kotlin 的高级写法时,我并不确定这些写法能不能够被初级工程师完全吸收或者理解。

当然这也可能仅仅是业务逻辑复杂的缘故,简单需求不会使用那么多高级特性,与其担心语法问题,不如担心其他人能不能理解其中的业务逻辑。

主要想探讨一下未来

我认为 kotlin 绝对有被广泛接受的资格,在绝大部分场景下去完全的替换 java 不是问题。

但是在我将这个项目完全 kotlin 化的进程中,结合我目前所处公司的见闻和一些网上的论坛所看,我对于国内编程行业的能够大规模运用 kotlin 这个未来,并不是很乐观。

首先就是,我认为国内的大厂本身,java 大规模协作的代码专业水平确实不高,至少不是顶尖水平,在我刚开始工作头两年,被网上阿里巴巴 java 开发手册所吸引,觉得国内大厂出品不会差,本身这个手册也没什么问题。

直到 2021 年,我开始深入框架序列化,研究 fastjson 时,我才开始明白,流传度高的东西并不一定就是好的。在我目前写这篇文章时,github 上 fastjson 的 star 数量是 24.9k,而 jackson 只有区区的 7.6k。

连阿里巴巴自家的 nacos 项目都不使用 fastjson,当然 nacos 的源码比 fastjson 好一点,但是和国外顶尖的开源项目比,还是差了很多。

在国内呢,前有百度这种已经躺平的搜索平台,后有 gitee 这种一开始叫码云蹭热度,页面设计很落后,莫名其妙塞了很多功能的国内第一开源平台。

让我不得不有这种悲观的忧虑,期待着这样的互联网公司构建的技术环境推进新事物,是非常困难的。

更别提在很多小公司内部,对于技术不求进取,只求快速完成需求,没有外部大型互联网企业的推动,接触新事物就更加困难了。

但是我还是抱有一些希望,希望以后得国内环境诞生出一个热爱技术的环境,不再被固有思维束缚,勇于探索新的境界。


zxdposter
3.9k 声望3.5k 粉丝