IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 使用DSL增加代码的可读性 -> 正文阅读

[移动开发]使用DSL增加代码的可读性

最近学习了一下kotlin的DSL特性,感觉挺有趣的,可以极大的提升代码的可读性。DSL是domin specific language的缩写,中文名叫做领域特定语言,具体涉及到lambda表达式,invoke约定,中缀表达式,扩展函数这些技术细节。
如下所示,我们可以将代码写成这样,这段代码我们可以很清晰的看出执行了一个异步操作,在异步模块内,创建了一个json对象,然后再转到UI线程上执行。

doAsync {
    val json = JsonNode {
        "test1" to 1
        "test2" to 2
        "test3" to true
        "test4" {
            "key1" to 1.0
            "key2" {
                "key3" to 345
            }
        }
        "test5" to array(1,2,3,4,5)
    }
    println(json.toString())

    uiThread {
        this.button.setText("执行完毕")
        this.alert("哈哈哈哈哈")
    }
}

1.具体实现

1.1 lambda表达式

kotlin当中的lambda表达式,支持当最后一个参数是方法时,可以直接写在括号外,如果只有一个方法参数时,可以省略括号。所以我们就可以写出这样的两个方法:

fun doAsync(block:()->Unit){
    Thread(Runnable(block)).start()
}

fun uiThread(block: () -> Unit){
    this.runOnUiThread(block)
}

一个是异步执行的方法,一个是在ui线程执行的方法,然后调用的时候就可以写成如下方式:

doAsync {
    //子线程执行的逻辑
    uiThread {
        //ui线程执行的逻辑
    }
}

对比java,代码简洁了非常多

new Thread(new Runnable() {
    @Override
    public void run() {
        //子线程执行的逻辑
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //ui线程执行的逻辑  
            }
        });
    }
}).start();

1.2 invoke约定+中缀表达式+扩展函数

目前很多库都已经将DSL玩出了花,比如:
html : https://github.com/Kotlin/kotlinx.html
可以非常直观的创建html,一目了然

html {
    body {
        div {
            a("https://kotlinlang.org") {
                target = ATarget.blank
                +"Main site"
            }
        }
    }
}

anko:https://github.com/Kotlin/anko
可以通过这种方式来写界面

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

得到如下的界面
在这里插入图片描述
其实这些库的实现方式就是用了 invoke约定,中缀表达式以及扩展函数。

我尝试着使用DSL方式实现创建json对象.
首先分析一下:

  1. 一串json其实就是一个Map,key是字符串,value可以是字符串,整型等基础数据,也可以是一个数组或者json对象,所以我们需要一个Map<String, Any>来存储这些数据;
  2. 我们想要实现"test" : “value”,这种对应关系,所以需要实现一个中缀表达式,然后将这个对应关系转换成entry,添加到map里面;
  3. 想要实现如下的方式写json,所以我们得针对String写一个invoke方法,能够将String变成key,方法体里面的内容变成value,存到map里。
"test1" {
  "key2" to 1.0
}

经过分析,我们可以写出如下代码:

class Node {

    val body: HashMap<String, Any> = HashMap()

    fun toJson(): JSONObject {
        val jsonObject = JSONObject()
        body.forEach {
            if (it.value is Node) {
                jsonObject.put(it.key, (it.value as Node).toJson())
            } else {
                jsonObject.put(it.key, it.value)
            }
        }
        return jsonObject
    }

    //invoke约定和扩展方法
    inline operator fun String.invoke(block: Node.() -> Unit): Node {
        val node = Node()
        node.block()
        this@Node.body[this] = node
        return node
    }

    //中缀表达式
    infix inline fun <T> String.to(value: T) {
        this@Node.body[this] = value!!
    }
}

fun JsonNode(block: Node.() -> Unit): JSONObject {
    val node = Node()
    node.block()
    return node.toJson()
}

fun <T> array(vararg values: T): JSONArray {
    val jsonArray = JSONArray()
    for (value in values) {
        jsonArray.put(value)
    }
    return jsonArray
}

使用方式如下:

JsonNode {
    "test1" to 1
    "test2" to 2
    "test3" to true
    "test4" {
        "key1" to 1.0
        "key2" {
            "key3" to 345
        }
    }
    "test5" to array(1,2,3,4,5)
}

然后我们就可以得到这样的json脚本

{
    "test4": {
        "key1": 1,
        "key2": {
            "key3": 345
        }
    },
    "test5": [
        1,
        2,
        3,
        4,
        5
    ],
    "test2": 2,
    "test3": true,
    "test1": 1
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-23 10:58:30  更:2022-04-23 10:58:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:31:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码