当前位置: 首页 > news >正文

Kotlin基础——DSL

DSL(领域特定语言)

常见的DSL就是SQL和正则表达式,用于操作数据库和文本字符串,Kotlin DSL通常为嵌套的Lambda表达式或链式方法,如

  • https://github.com/gradle/gradle-script-kotlin 用于构建Gradle脚本
  • https://github.com/JetBrains/Exposed 用于操作数据库
  • https://github.com/Kotlin/kotlinx.html 用于生成HTML

带接收者的Lambda和扩展函数类型

对于普通的生成字符串函数,需要在Lambda中使用it指向StringBuilder实例

fun buildString(builderAction: (StringBuilder) -> Unit): String {val sb = StringBuilder()builderAction(sb)return sb.toString()
}val s = buildString {it.append("Hello ")it.append("World")
}println(s)

转换为带接收者的Lambda可通过this或直接调用方法

fun buildString(builderAction: StringBuilder.() -> Unit): String {val sb = StringBuilder()sb.builderAction()return sb.toString()
}val s = buildString {this.append("Hello ")append("World")
}println(s)

具体做法是使用扩展函数类型取代普通函数类型来声明参数的类型,将函数类型签名中的一个参数移到括号前面,并用一个.分割

(StringBuilder) -> Unit		//一个接收StringBuild参数、无返回值的函数
StringBuilder.() -> Unit	//将(接收者对象)参数往前移

也声明一个扩展函数类型的变量

val appendExcl: StringBuilder.() -> Unit = { this.append("!") }
val sb = StringBuilder("Hi")
sb.appendExcl()
println(sb)

Kotlin标准库中的apply和with就是利用扩展函数类型

public inline fun <T> T.apply(block: T.() -> Unit): T {.....block()			//apply的接收者被当作lambda的接收者return this		//返回接收者
}public inline fun <T, R> with(receiver: T, block: T.() -> R): R {......return receiver.block()		//返回调用Lambda的结果
}

HTML构建器

用于Html的Kotlin DSL叫做HTML构建器,其是类型安全的

open class Tag(val name: String) {private val children = mutableListOf<Tag>()protected fun <T : Tag> doInit(child: T, init: T.() -> Unit) {child.init()children.add(child)}override fun toString() = "<$name>${children.joinToString("")}</$name>"
}fun table(init: TABLE.() -> Unit) = TABLE().apply(init)class TABLE : Tag("table") {fun tr(init: TR.() -> Unit) = doInit(TR(), init)
}class TR : Tag("tr") {fun td(init: TD.() -> Unit) = doInit(TD(), init)
}class TD : Tag("td")fun createTable() =table {tr {td {}}}

调用

println(createTable())<table><tr><td></td></tr></table>

invoke约定

重写invoke()可以让对象像函数一样调用,p(1)会被编译成p.invoke(1)

class Person(val name: String) {operator fun invoke(age: Int) {println("$name,$age")}
}val p = Person("A")
p(1)

Gradle中的DSL

class DependencyHandler {fun compile(coordinate: String) {println("add dependency on $coordinate")}operator fun invoke(body: DependencyHandler.() -> Unit) {body()}
}val dependencies = DependencyHandler()dependencies.compile("com.demo.demo-lib:1.0.0")dependencies {compile("com.demo.demo-lib:1.0.0")
}

中缀调用的DSL

对于下面的DSL

infix fun <T> T.should(matcher: Matcher<T>) = matcher.test(this)interface Matcher<T> {fun test(value: T)
}class startWith(val prefix: String) : Matcher<String> {override fun test(value: String) {if (!value.startsWith(prefix)) {throw AssertionError("$value does not start with $prefix")}}

可使用中缀调用

"kotlin" should startWith("kot")"kotlin".should(startWith("kot"))

还可利用包装类进一步简化,利用obetject对象选择不同类型的should()重载方法

object start
infix fun String.should(x: start): StartWrapper = StartWrapper(this)
class StartWrapper(val value: String) {infix fun with(prefix: String) =if (!value.startsWith(prefix))throw AssertionError("$value does not start with $prefix")elseprintln("success")
}
"kotlin" should start with ("kot")"kotlin".should(start).with("kot")

基本数据类型上定义扩展

val Int.days: Periodget() = Period.ofDays(this)val Period.ago: LocalDateget() = LocalDate.now() - thisval Period.fromNow: LocalDateget() = LocalDate.now() + this

通过扩展函数实现获取一天前和一天后的日期

println(1.days.ago)
println(1.days.fromNow)

相关文章:

Kotlin基础——DSL

DSL&#xff08;领域特定语言&#xff09; 常见的DSL就是SQL和正则表达式&#xff0c;用于操作数据库和文本字符串&#xff0c;Kotlin DSL通常为嵌套的Lambda表达式或链式方法&#xff0c;如 https://github.com/gradle/gradle-script-kotlin 用于构建Gradle脚本https://gith…...

《Docker 简易速速上手小册》第4章 Docker 容器管理(2024 最新版)

文章目录 4.1 容器生命周期管理4.1.1 重点基础知识4.1.2 重点案例&#xff1a;启动并管理 Python Flask 应用容器4.1.3 拓展案例 1&#xff1a;调试运行中的容器4.1.4 拓展案例 2&#xff1a;优雅地停止和清理容器 4.2 容器数据管理与持久化4.2.1 重点基础知识4.2.2 重点案例&a…...

【人脸朝向识别与分类预测】基于PNN神经网络

课题名称&#xff1a;基于PNN神经网络的人脸朝向识别分类 版本日期&#xff1a;2024-02-20 运行方式&#xff1a;直接运行PNN0503.m文件 代码获取方式&#xff1a;私信博主或 QQ:491052175 模型描述&#xff1a; 采集到一组人脸朝向不同角度时的图像&#xff0c;图像来自不…...

【Python笔记-设计模式】组合模式

一、说明 组合模式是一种结构型设计模式&#xff0c; 你可以使用它将对象组合成树状结构&#xff0c; 并且能像使用独立对象一样使用它们。 (一) 解决问题 处理树形结构&#xff1a;可以很好地处理树形结构的数据&#xff0c;使得用户可以统一对待单个对象和对象组合。统一接…...

51单片机学习(5)-----蜂鸣器的介绍与使用

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 目录 一. 蜂鸣器的介绍 1.蜂鸣器介绍 2.压电式蜂鸣器 &#xff08;无源…...

-bash: /root/.ssh/authorized_keys: Read-only file system

问题背景 由于跳板机不支持 ssh-copy-id 命令&#xff0c;为了配置免密登录&#xff0c;考虑在服务器上手动使用 cat 命令写入跳板机公钥 cat <<EOL >> ~/.ssh/authorized_keys [Your public key] EOL但却出现了以下错误 -bash: /root/.ssh/authorized_keys: Re…...

3,设备无关位图显示

建立了一个类Dib Dib.h #pragma once #include “afx.h” class CDib :public CObject { public: CDib(); ~CDib(); char* GetFileName(); BOOL IsValid(); DWORD GetSize(); UINT GetWidth(); UINT GetHeight(); UINT GetNumberOfColors(); RGBQUAD* GetRGB(); BYTE* GetDat…...

转前端了!!

大家好&#xff0c;我是冰河~~ 没错&#xff0c;为了更好的设计和开发分布式IM即时通讯系统&#xff0c;也为了让大家能够直观的体验到分布式IM即时通讯系统的功能&#xff0c;冰河开始转战前端了。也就是说&#xff0c;整个项目从需求立项到产品设计&#xff0c;从架构设计到…...

RESTful API如何使用它构建 web 应用程序。

链接&#xff1a;华为机考原题 RESTful API(Representational State Transfer)是一种基于网络的软件架构风格&#xff0c;用于设计和访问网络资源。它是一种轻量级、灵活、可扩展的架构&#xff0c;常用于构建Web应用程序和服务。 使用RESTful API构建Web应用程序的步骤如下&…...

现在学Oracle是49年入国军么?

今天周末&#xff0c;不聊技术&#xff0c;聊聊大家说的最多的一个话题 先说明一下&#xff0c;防止挨喷&#x1f606; 本人并不是职业dba&#xff0c;对数据库就是爱好&#xff0c;偶尔兼职&#xff0c;以下仅个人观点分析&#xff0c;如有不同观点请轻喷&#xff0c;哈哈&…...

【回溯】组合问题||

给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含重复的组合。 示例 1: 输入: candidates [10,1,2,7,6,…...

【c语言】字符函数和字符串函数(下)

前言 书接上回 【c语言】字符函数和字符串函数(上) 上一篇讲解的strcpy、strcat、strcmp函数的字符串长度是不受限制的 而本篇strncpy、strncat、strcnmp函数的字符串长度是受限制的 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;…...

基于Java的艺培管理解决方案

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…...

Python算法题集_实现 Trie [前缀树]

Python算法题集_实现 Trie [前缀树] 题208&#xff1a;实现 Trie (前缀树)1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【定义数据类默认字典】2) 改进版一【初始化字典无额外类】3) 改进版二【字典保存结尾信息无额外类】 4. 最优算法5. 相关…...

pytorch简单新型模型测试参数

import torch from torch.nn import Conv2d,MaxPool2d,Sequential,Flatten,Linear import torchvision import torch.optim.optimizer from torch.utils.data import DataLoader,dataset from torch import nn import torch.optim.optimizer# 建模 model nn.Linear(2,1)#损失 …...

Unity中URP下实现水体(水面高光)

文章目录 前言一、实现高光反射原理1、原理&#xff1a;2、公式&#xff1a; 二、实现1、定义 _SpecularColor 作为高光反射的颜色2、定义 _SpecularIntensity 作为反射系数&#xff0c;控制高光反射的强度3、定义 _Smoothness 作为高光指数&#xff0c;用于模型高光范围4、模拟…...

26.HarmonyOS App(JAVA)列表对话框

列表对话框的单选模式&#xff1a; //单选模式 // listDialog.setSingleSelectItems(new String[]{"第1个选项","第2个选项"},1);//单选 // listDialog.setOnSingleSelectListener(new IDialog.ClickedListener() { // Override …...

五种主流数据库:常用字符函数

SQL 字符函数用于字符数据的处理&#xff0c;例如字符串的拼接、大小写转换、子串的查找和替换等。 本文比较五种主流数据库常用数值函数的实现和差异&#xff0c;包括 MySQL、Oracle、SQL Server、PostgreSQL 以及 SQLite。 字符函数函数功能MySQLOracleSQL ServerPostgreSQ…...

软考笔记--企业资源规划和实施

企业资源是指企业业务活动和战略运营的事物&#xff0c;包括人、财和物&#xff0c;也包括信息资源&#xff0c;同时也包括企业的内部和外部资源。企业资源可以归纳为物流&#xff0c;资金流和信息流。企业资源规划&#xff08;ERP&#xff09;是只建立在信息技术基础上&#x…...

React歌词滚动效果(跟随音乐播放时间滚动)

首先给audio绑定更新时间事件 const updateTime e > {console.log(e.target.currentTime)setCurrentTime(e.target.currentTime);};<audiosrc{currentSong.url}ref{audio}onCanPlay{ready}onEnded{end}onTimeUpdate{updateTime}></audio>当歌曲播放时间改变的时…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...