使用Kotlin轻松进行DSL设计

在Android中,每门教您基础知识的教程都描述了如何通过XML文件设计屏幕。 使用Java(或任何基于JVM的语言)也可以达到相同的结果。 Android屏幕设计不是XML和Java是有效选项的唯一领域。 例如,Spring配置和Vaadin屏幕设计都可以。 然而,在所有这些领域中,都需要权衡取舍:一方面,XML具有由XML模式强制执行的相当严格的结构,而Java却以牺牲可读性为代价提供了执行任何操作的能力。 “拥有权利的同时也被赋予了重大的责任”。 在后一种情况下,由单个开发人员来行使他/她的判断,以使代码尽可能地可读。

领域特定的语言位于频谱的这两端之间,因为它们提供了一种结构化的语法,可以解决当前的问题,但在必要时会完全支持基础语言结构。 例如,AssertJ库使用流利的API为声明提供DSL。 以下摘录摘自其文档:

// entry point for all assertThat methods and utility methods (e.g. entry)
importstaticorg.assertj.core.api.Assertions.*;

// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
                               .contains(frodo,sam)
                               .doesNotContain(sauron);

DSL可以以任何语言提供,即使有些人觉得更自然。 自然地会想到Scala,但Kotlin也非常适合。 回到Android,Jetbrains提供了出色的Anko库,可以使用基于Kotlin的DSL设计Android屏幕。 以下代码片段突出显示了Anko(摘自文档):

verticalLayout{
    valname=editText()
    button("Say Hello"){
        onClick{toast("Hello, ${name.text}!")}
    }
}

为此需要两种Kotlin语言构造。

扩展功能

我已经写过关于扩展功能的文章,所以我会很快介绍它。 本质上, 扩展功能是一种将行为添加到现有类型的方法。

例如, String具有设置大小写的方法,但没有大写字母。 使用扩展功能,很容易就能填补空白:

funString.toCapitalCase()=when{
    length<2->toUpperCase()
    else->this[0].toUpperCase()+substring(1).toLowerCase()
}

此时,用法很简单: "foo".toCapitalCase()

最重要的一点就是使用this在上面的代码片段:它指的是实际的字符串实例。

功能类型

在Kotlin中,功能类型。 在所有后果中,这意味着函数可以作为函数参数传递。

fundoSomethingWithInt(value:Int,f:(Int)->Unit){
    value.apply(f);
}

上面的函数现在可以传递任何以Int作为参数并返回Unit函数, 例如 { print(it) } 。 这样称呼:

doSomethingWithInt(5,{print(it)})

现在,Kotlin在调用方法时提供了语法糖:如果lambda是函数调用中的最后一个参数,则可以将其与其他参数分开,如下所示:

doSomethingWithInt(5){print(it)}

放在一起

回到上面Anko代码片段 ,让我们检查一下如何定义verticalLayout { …​ }方法:

inlinefunViewManager.verticalLayout(theme:Int=0,init:_LinearLayout.()->Unit):LinearLayout{
    returnankoView(`$$Anko$Factories$CustomViews`.VERTICAL_LAYOUT_FACTORY,theme,init)
}

如第一段所示, init参数是在_LinearLayout类型上定义的扩展函数。 在上下文中使用的this将引用后一种类型的实例。

第二段解释了代表括号内容的内容: init参数函数。

结论

希望这篇文章展示了使用Kotlin创建DSL的语法是多么容易。

我开发了一种这样的DSL来为Vaadin框架创建GUI:名称为Kaadin,结果可在线获得

翻译自: https://blog.frankel.ch/easy-dsl-design-with-kotlin/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值