Kotlin领域特定语言(DSL)

简介: 一、DSL的概念 只在特定领域内使用的语言 例如: —HTML、Gradle、SQL等等特点: 计算机编程语言 具有语言的表达能力 有限的表达能力 关注某个特定的领域二、下面用DSL来写一个例子吧 需要下面五个类: 三、创建一个Node节点的接口package cn.

一、DSL的概念
只在特定领域内使用的语言
例如:
—HTML、Gradle、SQL等等

特点:
计算机编程语言
具有语言的表达能力
有限的表达能力
关注某个特定的领域

二、下面用DSL来写一个例子吧
需要下面五个类:
这里写图片描述

三、创建一个Node节点的接口

package cn.kotliner.kotlin

/**
 * @author:wangdong
 * @description:1.Node节点的接口
 */
interface Node {
    //每个节点都应该有一个render方法
    //例如对于HTML标签,它的render方法应该输出什么
    fun render(): String
}

四、写一个通用的Tag类,实现这个接口

package cn.kotliner.kotlin

/**
 * @author:wangdong
 * @description:2.通用的tag类
 */
/***
 * 实现了Node接口
 * Tag类需要Open,以便其他类继承
 */
open class Tag(val name: String): Node{

    //1.定义一个Node节点的list
    val children = ArrayList<Node>()
    //定一个表现属性的Map
    val properties = HashMap<String,String>()

    //定义一个String的扩展方法,参数是String
    operator fun String.invoke(value: String){
        properties[this] = value
    }

    //定义一个String加法的拓展
    operator fun String.unaryPlus(){
        children.add(StringNode(this))
    }

    //定义一个添加运算符
    operator fun plus(node: Node){
        children.add(node)
    }

    //定义一个String的扩展方法,参数是Tag.()
    operator fun String.invoke(block: Tag.() -> Unit){
        children.add(Tag(this).apply(block))
    }

    //例如<html id = "htmlId" style = ""><head></head><body></body></html>

    // <html id="htmlId" style=""><head> </head> <body></body></html>
    override fun render(): String {
        return StringBuilder()
                .append("<")
                .append(name)
                .let {
                    stringBuilder ->
                    if(!this.properties.isEmpty()){
                        stringBuilder.append(" ")
                        this.properties.forEach{
                            stringBuilder.append(it.key)
                                    .append("=\"")
                                    .append(it.value)
                                    .append("\" ")
                        }
                    }
                    stringBuilder
                }
                .append(">")
                .let {
                    stringBuilder ->
                    children.map(Node::render).map(stringBuilder::append)
                    stringBuilder
                }
                .append("</$name>")
                .toString()
    }

}

五、写一个主函数

package cn.kotliner.kotlin

/**
 * @author:wangdong
 * @description:3.写一个主函数
 */
fun main(args: Array<String>) {
    //定义一个tag
    //给它添加一个属性
    /*Tag("html").apply {
        properties["id"] = "Htmlid"
        //给节点添加一个tag
        children.add(Tag("head"))
    }.render().let(::println)*/

    //此时代码可以改一下了
    html{
        "id"("HtmlId")
        //给节点添加一个tag
        //children.add(Tag("head"))
        "head"{
            "id"("headId")
        }

        body{

            id = "bodyId"
            `class` = "bodyClass"
            "a"{
                "href"("https://www.kotliner.cn")
                + "Kotlin中文博客"
            }
        }

        "div"{}
    }.render().let(::println)
}

六、写一个Nodes,用来写各种方法

package cn.kotliner.kotlin

/**
 * @author:wangdong
 * @description:4.定一个Nodes
 */
fun html(block: Tag.() -> Unit): Tag{
    //首先new了一个Tag,名字叫html,用它的作用域去调用了一下block,传的this就是Tag("html")
    return Tag("html").apply(block)
}

/**
 * head的拓展方法
 * 要是tag的扩展方法
 * 不需要返回值
 */
fun Tag.head(block: Head.() -> Unit){
    this@head + Head().apply(block)
}
/**
 * body的拓展方法
 */
fun Tag.body(block: Body.() -> Unit){
    this@body + Body().apply(block)
}

/**
 * 定义一个节点
 * 参数content
 * 返回值:Node
 */
class StringNode(val content: String):Node{
    override fun render() = content
}
/**定义头*/
class Head: Tag("head")

/**定义体*/
class Body: Tag("body"){
    var id by MapDelegate(properties)

    var `class` by MapDelegate(properties)
}

七、定义一个MapDelegate用来Set或者Get值

package cn.kotliner.kotlin

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
 * @author:wangdong
 * @description:5.定义一个mapDelegate
 */

/**
 * map是可读写的
 * 实现一个接口
 */
class MapDelegate(val map: MutableMap<String,String>):ReadWriteProperty<Any,String>{
    /**
     * Returns the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @return the property value.
     * 返回值
     */
    override fun getValue(thisRef: Any, property: KProperty<*>): String {
        return map[property.name] ?: ""
    }

    /**
     * Sets the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @param value the value to set.
     * 设置值
     */
    override fun setValue(thisRef: Any, property: KProperty<*>, value: String) {
        map[property.name] = value
    }
}

八、运行一下主方法
得到的输出结果:

<html id="HtmlId" ><head id="headId" ></head><body id="bodyId" class="bodyClass" ><a href="https://www.kotliner.cn" >Kotlin中文博客</a></body></html>

好啦,结束啦!

目录
相关文章
|
3月前
|
XML 编译器 Android开发
Kotlin DSL 实战:像 Compose 一样写代码
Kotlin DSL 实战:像 Compose 一样写代码
59 0
|
XML 自然语言处理 Java
Kotlin 使用DSL构建语法结构 看这一篇就够了~
Kotlin 使用DSL构建语法结构 看这一篇就够了~
1523 0
Kotlin 使用DSL构建语法结构 看这一篇就够了~
|
9天前
|
Java Android开发 C++
Kotlin vs Java:选择最佳语言进行安卓开发
【4月更文挑战第13天】Java曾是安卓开发的主流语言,但Kotlin的崛起改变了这一局面。Google在2017年支持Kotlin,引发两者优劣讨论。Java以其成熟稳定、强大生态和跨平台能力占优,但代码冗长、开发效率低和语言特性过时是短板。Kotlin则以简洁语法、空安全设计和高度兼容Java脱颖而出,但社区和生态系统仍在发展中,可能存在学习曲线和性能问题。选择语言应考虑项目需求、团队熟悉度、维护性、性能和生态系统。无论选择哪种,理解其差异并适应新技术至关重要。
|
8月前
|
API Kotlin
Kotlin中扩展函数、infix关键字、apply函数和DSL的详解
Kotlin中扩展函数、infix关键字、apply函数和DSL的详解
76 0
|
10月前
|
XML 安全 Java
使用Kotlin构建Android应用:现代化的开发语言
随着移动应用开发的不断发展,开发人员有了更多选择来构建功能强大、高效和可维护的Android应用程序。其中一种备受推崇的选择就是使用Kotlin作为开发语言。Kotlin是一种现代化的编程语言,它为Android开发带来了许多优势和便利。
107 0
|
11月前
|
算法 安全 Java
00. Kotlin 安装和语言的基本组成
00. Kotlin 安装和语言的基本组成
197 0
|
SQL 存储 NoSQL
JVM 上数据处理语言的竞争:Kotlin, Scala 和 SPL
JVM 上数据处理语言的竞争:Kotlin, Scala 和 SPL
198 0
|
SQL 存储 NoSQL
JVM 上数据处理语言的竞争:Kotlin, Scala 和 SPL
基于JVM的开源数据处理语言主要有Kotlin、Scala、SPL,下面对三者进行多方面的横向比较,从中找出开发效率最高的数据处理语言。本文的适用场景设定为项目开发中常见的数据处理和业务逻辑,以结构化数据为主,大数据和高性能不作为重点,也不涉及消息流、科学计算等特殊场景。......
192 0
JVM 上数据处理语言的竞争:Kotlin, Scala 和 SPL
|
XML 前端开发 JavaScript
用kotlin来实现dsl风格的编程
用kotlin来实现dsl风格的编程
251 0
用kotlin来实现dsl风格的编程
|
Java Android开发 C++
【Android NDK 开发】Kotlin 语言中使用 NDK ( 创建支持 Kotlin 的 NDK 项目 | Kotlin 语言中使用 NDK 要点 | 代码示例 )(二)
【Android NDK 开发】Kotlin 语言中使用 NDK ( 创建支持 Kotlin 的 NDK 项目 | Kotlin 语言中使用 NDK 要点 | 代码示例 )(二)
172 0
【Android NDK 开发】Kotlin 语言中使用 NDK ( 创建支持 Kotlin 的 NDK 项目 | Kotlin 语言中使用 NDK 要点 | 代码示例 )(二)