切底掌握Android中的Kotlin DSL

news2024/12/24 2:07:25

前言

在这篇文章中,我们将学习如何在您的 Android 项目中编写 Kotlin DSL。

这个文章会很长,所以花点时间,让我们一起来写你的 DSL。我们将讨论以下主题,

  • 什么是简单英语中的 DSL?
  • 您使用任何 DSL 吗?
  • 为什么我们使用 DSL?
  • 我们如何编写自己的 DSL
  • 基本示例说明。

那么让我们开始吧。

什么是 DSL?

维基百科的定义说,

领域特定语言( DSL) 是专门针对特定应用领域的计算机语言。这与广泛适用于跨领域的通用语言(GPL)形成对比。

喜欢认真吗?

一般而言,DSL 为您提供了任何特定语言的灵活工具,以利用特定编程语言提供的功能。

您使用任何 DSL 吗?

如果您是一名 android 开发人员并且在您的项目中使用 kotlin,您可能会有意或无意地在您的项目中使用 DSL?你能想出一个例子吗?

让我帮你,你有没有写过类似的代码,

yourlist.forEach { 
    //your code is here
}

上面的例子是在 Kotlin 的列表中使用forEach。forEach is kotlin 是 DSL 的一个例子

为什么我们使用 DSL?

我们应该使用 DSL 来简化和提高应用程序的复杂性,并使代码更具可读性。

我们如何编写自己的 DSL?

在开始编写我们自己的 DSL 之前,我们需要了解带有接收器的 lambda。
但也让我简要概述一下 lambda with receiver

假设我们有一个函数 buildString,

fun buildString(action: (StringBuilder).() -> Unit): String {
    val stringBuilder = StringBuilder()
    action(stringBuilder)
    return stringBuilder.toString()
}

在这里,我们有一个函数buildString,它将动作(它是一个函数)作为参数。此处的action函数以StringBuilder作为参数,函数buildString以 String 作为返回类型。

现在,要使用我们编写的buildString ,

buildString {
    append("<")
    append("MindOrks")
    append(">")
}

我们在这里使用 Kotlin 的属性来传递与 StringBuilder 相关的属性,因为我们在buildString函数中使用了扩展函数的强大功能。

我们还可以使用创建自定义 DSL,

中缀

在 Kotlin 中,中缀帮助我们创建自定义 DSL,类似于我们用英语编写的方式。例如,

在英语中,我们说“1加2”来求和或求差,我们说“1减2”。使用中缀调用可以在 Kotin 中实现类似的事情。

为了创建一个中缀来添加我们使用的数字,

infix fun Int.plus(number: Int) = this + number

在这里,我们创建了一个 Int 的扩展函数,加上它接受一个数字并返回这个 + 数字的总和。这是应用函数的数字。

所以,要使用我们使用的这个中缀函数,

val output = 1 plus 2

在上面的代码中,我们使用我们创建加号的中缀函数来生成输出。当我们在 Logcat 中打印它时,它会打印3作为总和。

这是因为我们创建了一个中缀扩展函数来使用加号文本代替“ + ”,我们将其用作传统方式。

同样,如果我们想让中缀函数减号,我们使用

infix fun Int.minus(number: Int) = this - number

为了使用它,我们使用,

val output = 1 minus 2

中缀使代码具有可读性并且非常有序,任何人都可以阅读。因此,如果任何对编程一无所知的人也可以说这是对两个数字进行加法或减法。

调用

在调用中,运算符允许将任何对象作为函数调用。在这里,让我们创建一个名为Student的类,

class Student {
    operator fun invoke(student: Student.() -> Unit) = student
    fun addName(name: String) {
        //implementation
    }
    fun addMarks(marks: Int) {
        //implementation
    }
}

在类中,我们创建了一个函数调用,它接受一个学生类型的参数并返回学生本身。所以,这里我们可以在student本身的对象中使用Student类的所有方法。

现在,要使用 Class,我们仍然会像在 Kotlin 中一样创建对象,

val student = Student()

现在你可以看到我们有另一个函数叫做addName addMarks**我们将把它用作 DSL。但是,在这里我们可以以两种不同的方式使用它。两者如下,

  1. 类型 - 1(传统方式)
student.addName("MindOrks")
student.addMarks(100)

上面的代码就像我们以前在 Android 中做的旧的传统方式。2.DSL方式

student {
    addName("MindOrks")
    addMarks(100)
}

在这里,我们使用 Kotlin DSL。如果你注意到了,我们有类似的 lambda,

Student.() -> Unit

如果你注意到了,我们在那里有一个.()。它指定 lambda 有一个接收器,要使用它,我们需要创建一个类的构造。这就是您可以使用调用来创建 DSL 的方式。

通过以上方式,您可以在 Kotlin 中创建您赢得的 DSL。

现在,让我们讨论 Android 中 DSL 的用例和示例。

  1. 数据类

在此,让我们讨论如何创建数据类的 DSL。考虑我们有一个数据类 Student

data class Student(
    var name: String? = null,
    var age: Int? = null,
    var marks: Int? = null
)

在此,如果我们使用我们编写的数据类,

val student =  Student(
      "MindOrks",
      20,
      30
  )

现在要在 DSL 中转换上述代码,

现在我们将创建一个新的 lambda,如下所示,

fun student(student: Student.() -> Unit): Student = Student().apply(student)

在上面的代码中,

我们有一个接收器,参数为 student 并将其用作我们使用的 DSL,

val student = student {
    name = "MindOrks"
    age = 20
    marks = 30
}

这就是我们可以将数据类转换为 DSL 的方法。

  1. UI 元素

为此,让我们将 textView 视为 UI 元素。在那,我们使用如下,

textView.text = "MindOrks"
textView.setOnClickListener {  
    
} 
textView.setTextColor(Color.BLACK)

但是要通过我们使用的 DSL 使用它,

textView.apply {
    text = "MindOrks"
    setOnClickListener {

    }
    textColor(Color.BLACK)
}

我们使用apply在任何 UI元素中创建 DSL

  1. JSON

在我们使用的 Android 中创建 JSON,

val jsonObject = JSONObject()
jsonObject.put("name","MindOrks")
jsonObject.put("age",20)

这是创建 JSON 对象的传统方式。

现在,让我们看看如何创建 DSL 来创建 JSON。首先,我们将创建一个类并使用 JSONObject() 对其进行扩展,

class Json() : JSONObject() {

}

现在,我们将使用带有接收器的 lambda 构造函数

constructor(json: Json.() -> Unit) : this() {
    this.init()
}

将使用中缀创建一个泛型来向 JSON 对象添加值。

看起来像,

infix fun <T> String.to(value: T) {
    put(this, value)
}

在这里,它将使用字符串键放置值,而值将使用“ to”的类型。

现在,完整的类文件看起来像,

class Json() : JSONObject() {

    constructor(json: Json.() -> Unit) : this() {
        this.json()
    }

    infix fun <T> String.to(value: T) {
        put(this, value)
    }
}
为了在 Activity 文件中使用它,我们使用刚刚创建的 DSL 创建 JSON,

val json = Json {
    "name" to "MindOrks"
    "age" to 20
}

这里,

  • to是我们为将值放入 JSON 对象而创建的中缀。
  • JSON 是我们创建的类,它使用键和值来创建 JSON 对象。

当我们在 Logcat 中打印它时,我们得到以下输出,

{"name":"MindOrks","age":20}

这就是您可以在 kotlin 代码中创建 DSL 的方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务的文件配置

1 基于本地文件配置的痛点 ①修改本地配置文件 需要重启服务 ②viper能监听本地配置文件变动 修改内存中变量的值 貌似可以满足需求 痛点如果实例过多 手动改极有可能出错 很多服务都依赖一个配置 运维可以写脚本批量修改 出问题运维不想背锅 ③ 多语言开发的实例 使用…

ThreadX在mdk(AC5)中的移植

1.ThreadX简介 Threadx是由 Express Logic 公司开发的一款实时操作系统&#xff08;RTOS&#xff09;&#xff0c;2019年被微软收购&#xff0c;成为了微软的一款Azure RTOS。在2020年&#xff0c;ThreadX也加入了开源大军&#xff0c;将ThreadX内核及其各大组件开源免费。 Th…

电赛汇总(一):微控制器以其外围电路模块设计

电赛汇总(一)&#xff1a;微控制器以其外围电路模块设计 这一章节主要详细记录各种常用的微控制器的引脚功能、外围的电路模块等&#xff0c;以便随时查看翻阅。这部分内容出自黄智伟等学者著的《全国大学生电子设计竞赛教程–常用电路模块制作》一书中&#xff0c;感兴趣的朋…

PS2022版本修复打开闪退问题

前言 windows 11 系统最近换了一台电脑&#xff0c;重新装了一批摄影剪辑软件&#xff0c;在使用过程中发现 PS2022 版本一但导入图片就卡死闪退。起初我以为是版本不兼容问题&#xff0c;但是问了一下对应的朋友他们并未出现这种情况。后面我就从百度中开始捞答案&#xff0c…

适用于平坦草原的近地层以上风廓线推算方法

目录 引言1 数据观测和处理1.1 观测实验和仪器1.2 数据处理 引言 本文研究平坦草原近地层之上的风廓线特征&#xff0c;尤其是不同稳定度情况下风随高度的变化&#xff1b;得到适用于本地的粗糙度、边界层高度和地转风的估测方法。 在上述研究的基础上&#xff0c;本文用上述…

如何快速的阅读一本书

B站&#xff1a;【读书方法】读不进&#xff1f;记不住&#xff1f;5分钟教你如何快速高效读书 | 读书会犯的5大错误&#xff01; 1 看着书皮&#xff0c;思考一下自己为什么读这本书&#xff0c;是为了解决什么问题。 2 要看目录&#xff0c;根据目录看一下这本书能不能解决…

0002Java程序设计-SSM协同过滤算法的新闻推荐系统

摘 要 “互联网”的战略实施后&#xff0c;很多行业的信息化水平都有了很大的提升。但是目前很多行业的管理仍是通过人工管理的方式进行&#xff0c;需要在各个岗位投入大量的人力进行很多重复性工作&#xff0c;使得对人力物力造成诸多浪费&#xff0c;工作效率不高等情况&am…

FPGA时序约束--实战篇(读懂Vivado时序报告)

目录 一、新建工程 二、时序报告分析 1、打开时序报告界面 2、时序报告界面介绍 3、时序路径分析 三、总结 FPGA开发过程中&#xff0c;vivado和quartus等开发软件都会提供时序报告&#xff0c;以方便开发者判断自己的工程时序是否满足时序要求。 本文将详细介绍如何读懂…

VLAN基础知识3_VLAN间三层通信(VLANIF接口)

目录 1.VLAN间三层通信简介 2.VLAN间三层通信方式 3.VLANIF接口介绍 4.基于VLANIF接口VLAN间三层通信原理 5.VLAN间三层通信实验 5.1 常用配置命令 5.2 配置步骤 5.3 实验效果 1.VLAN间三层通信简介 VLAN间三层通信是指在VLAN网络中&#xff0c;不同VLAN之间进行IP通信…

python也可以使用克里金插值算法吗?

挪威大陆架的声学压缩慢度测量的空间变化 在处理地质和岩石物理数据时&#xff0c;我们通常希望了解这些数据在我们的地区是如何变化的。我们可以做到这一点的方法之一是对我们的实际测量值进行网格化&#xff0c;并推断这些值。 进行这种外推的一种特殊方法是克里金法&#xf…

三阶魔方有多少种状态

魔方有 3 种不同的方块&#xff0c;分别为角块&#xff08;8 个&#xff0c;每个角块有三种颜色&#xff09;&#xff0c;棱块&#xff08;12 个&#xff0c;每个棱块有两种颜色&#xff09;与中心块&#xff08;6 个&#xff0c;每个中心块有一种颜色&#xff09;。 魔方总共…

每天学一点知识有用吗

在探索如何学习的路上&#xff0c;我注意到了基于微习惯的学习方式&#xff0c;比如每天在用十分钟的时间练习下普通话&#xff0c;或者每天写500字的总结。 我简单回顾一下&#xff1a; 这种方法虽然颇受欢迎&#xff0c;但是它限制了你可以尝试的活动种类&#xff0c;有时候…

深度学习(24)——YOLO系列(4)

深度学习&#xff08;24&#xff09;——YOLO系列&#xff08;4&#xff09; 文章目录 深度学习&#xff08;24&#xff09;——YOLO系列&#xff08;4&#xff09;1. dataset准备&#xff08;1&#xff09;数据详解&#xff08;2&#xff09;dataset&#xff08;3&#xff09;…

广告数仓:全流程调度

系列文章目录 广告数仓&#xff1a;采集通道创建 广告数仓&#xff1a;数仓搭建 广告数仓&#xff1a;数仓搭建(二) 广告数仓&#xff1a;全流程调度 文章目录 系列文章目录前言一、ClickHouse安装1.修改环境2.安装依赖3.单机安装4.修改配置文件5.启动clickhouse6.创建需要的数…

012-从零搭建微服务-接口文档(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

统一拦截--过滤器Filter

1.过滤器Filter 1. 概述 概念: Filter过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。过滤器一般完成一些通用的操作&#xff0c;比如:登录校验、统一编码处理、敏感字符处理等…

Tcp协议的十大特性详解+示例

前言 之前我们简单了解了一下Tcp是什么及它的套接字如何使用:基于UDP和TCP套接字实现简单的回显客户端服务器程序_Crystal_bit的博客-CSDN博客 因为要给大家介绍Tcp的十大特性&#xff0c;所以这里给出Tcp报头结构&#xff1a; 目录 1. 确认应答 2. 超时重传 3. 连接管理 3…

【Android复习笔记】Parcelable 为什么速度优于 Serializable ?

Q:Parcelable 为什么速度优于 Serializable ? 首先,抛开应用场景谈技术方案都是在耍流氓,所以如果你遇到有面试官问这样的题目本身就是在给面试者挖坑。 序列化 将实例的状态转换为可以存储或传输的形式的过程。 Serializable 实现方式: Serializable 是属于 Java 自带的…

Solid Converter PDF v10 安装及使用教程

目录 一、软件介绍二、下载教程三、安装教程四、使用教程1.PDF转Word、Html等2.合并PDF文件 一、软件介绍 Solid Converter PDF是一套专门将PDF文件转换成Word的软件。 能够将PDF转换为Word、Excel、HTML、PowerPoint、纯文本文件从PDF文档中提取数据并以CSV等格式保存能够转…

数仓工程师理解复杂业务的思考方法论

模型设计框架&#xff08;业务过程驱动&#xff09;还是在经典的三层数据模型架构下去进行&#xff0c;概念模型、逻辑模型、物理模型 首先概念模型其实是业务过程&#xff08;流程图&#xff09;&#xff0c;其中需要考虑到几个方面&#xff1a; 1.数据 业务覆盖 业务感知、…