当前位置: 首页 > 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>当歌曲播放时间改变的时…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...