Kotlin进阶之内部DSL

公众号「稀有猿诉」 原文链接 Understanding Kotlin Based DSL

DSL Domain Specific Langauge是解决特定领域内问题的编程语言,它的特点通常是简洁,虽不通用,但可读性强,呈描述式和声明式,比较典型的例子就是SQL语句和正则表达式,以及一些文本处理工具如Sed和AWK。与之对应的就是通用编程语言GPL General Purpose Language,能解决几乎所有的计算机问题,没有为特定领域进行定制,但语句可读性远不及DSL,它们的语句一般都是命令式的,如熟悉的C/C++, Java和Python等。

GPL中的DSL痛点

DSL的优点是声明式的,描述式的 ,并不在意具体细节的实现,比如像SQL语句,我只关心我想要什么,具体如何实现的是底下工具的事情:

SQL 复制代码
select (id, name, address)
    where name = "John" and age <= 10
    from classlist

但,当在GPL,通用编程语言中解决DSL问题时,就会很蛋疼,在任何一个编程语言中实现一个SQL查询 的接口都会相当的笨拙和难用,要么需要创建很多个对象,要么需要传递一大堆令人费解的参数:

Java 复制代码
    Cursor cursor = query(uri, projects, where, whereArgs, sortby);

可读性非常的差,假如能写成DSL那样,可读性会大大的增强。

DSL式的API

在Kotlin中,可以写成这样:

kotlin 复制代码
query {
    from "classlist"
    where {
        "name" eq "John"
        "age" lessEq 10
    }
}

可读性大大加强,这样的API使用起来也会如丝般顺滑,因为它符合DSL:描述性的,声明式的,不关心具体实现细节,只关注想要什么。

背后原理

Kotlin借助尾部lambda,infix函数,扩展函数。整体来就其实是一个函数调用,因为Kotlin函数最后一个参数如果是lambda时可以写在函数调用之外,所以,一层一层的花括号,其实就是函数调用。

再借助扩展函数和infix函数,可以把另外一些函数调用写成DSL式,比如像二进制按位或运算a or b等同于a.or(b),这也是一个函数调用,但可读性大大加强。可以像写不作文一样的来写代码。

总之,见到DSL式的语句时不用惊慌,它是合法的Kotlin函数调用,把它理解成为函数调用就可以了。

合理使用

虽然DSL式的API能大大提高可读性,像真正的DSL一样去使用,但也要注意合理使用,不能滥用。我们要正向的解决问题,当遇到特定领域(Domain)的问题时,就可以定义和实现出一套符合DSL的API。也就是说我们要利用Kotlin语言提供的能力来实现DSL式的API去解决特定领域的问题。就像Android的布局,就可以定义出一套DSL式的API,这就是当时比较火的anko(现已废弃了)和现在的Compose,以及像涉及HTML,SQL的等特定领域问题时。

但不能反过来,为了写成DSL式,而去把所有的API都搞成DSL那样,比如把一些常规的操作像网络,像文件操作等都搞成那样,那就纯属滥用了。

参考资料

欢迎搜索并关注 公众号「稀有猿诉」 获取更多的优质文章!

原创不易,「打赏」「点赞」「在看」「收藏」「分享」 总要有一个吧!

相关推荐
2401_873479401 小时前
如何利用IP查询定位识别电商刷单?4个关键指标+工具配置方案
开发语言·tcp/ip·php
我爱cope2 小时前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
菜鸟学Python2 小时前
Python生态在悄悄改变:FastAPI全面反超,Django和Flask还行吗?
开发语言·python·django·flask·fastapi
浪浪小洋3 小时前
c++ qt课设定制
开发语言·c++
冬奇Lab3 小时前
Android 开发要变天了:Google 专为 Agent 重建工具链,Token 减少 70%、速度提升 3 倍
android·人工智能·ai编程
charlie1145141913 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
故事和你913 小时前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论
程序猿编码4 小时前
给你的网络流量穿件“隐形衣“:手把手教你用对称加密打造透明安全隧道
linux·开发语言·网络·安全·linux内核
aq55356005 小时前
编程语言三巨头:汇编、C++与PHP大比拼
java·开发语言
aq55356005 小时前
PHP vs Python:30秒看懂核心区别
开发语言·python·php