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那样,比如把一些常规的操作像网络,像文件操作等都搞成那样,那就纯属滥用了。

参考资料

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

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

相关推荐
AI编码进化论6 分钟前
云IDE介绍:环境模板化、Agent上云,云IDE该怎么选
开发语言·ide·人工智能·团队开发·ai编程
mmsx6 分钟前
Android 几何构造器的双栈机:链式 API 底层是怎么装配几何的
android
mmsx6 分钟前
Android 地图卡成 PPT 之后:双渲染管线与空间网格渐进加载怎么救
android·app
晴天的雨.99211 分钟前
[C++算法]盛最多水的容器(双指针算法)
开发语言·c++·算法
泡海椒15 分钟前
jquick-pdf 文本元素实战:段落、行内文本、制表符用法详解
java·开发语言·pdf
光影少年15 分钟前
setImmediate 和 setTimeout(0) 的区别
android·前端·react.js·ios·前端框架
“AI国潮设计-小江”1 小时前
【SDXL实战】Python自动化生成3D潮汕美食IP,附ComfyUI工作流与商用变现思路
开发语言·人工智能·python·prompt·aigc
此生决int1 小时前
深入理解C++系列(19)——C++11(上)
开发语言·c++
郝学胜-神的一滴1 小时前
C++20模板元编程 05:吃透变参模板,解锁编译期万能参数能力
服务器·开发语言·c++·windows·vscode
C++ 老炮儿的技术栈11 小时前
我们在设计tcp协议时,要传一个字符串过去,报文:头十长度十内容,是否要把‘\0‘也填入,长度是否包含‘\0‘
开发语言·数据结构·c++·mfc·c