Kotlin委托
委托
委托 == 代理
方法内的成员永远拿不到thisRef:官方委托和自定义委托-》方法里面没办法使用反射
委托只能类委托和属性委托
Kotlin委托
本文链接:https://blog.csdn.net/feather_wch/article/details/132095759
类委托
1、类委托
- 委托的是接口的方法
// 只能用于接口
interface DB{fun save()
}
// 类CreateDBAction实现了接口DB,参数db是DB类型,类的实现委托给参数db。
// 目的:啥也不想干
class CreateDBAction(db: DB):DB by db
2、类委托的原理是什么?生成了什么代码?
- 成员变量:$$delegate_0 = 参数db
- 实现方法:委托给$$delegate_0调用save()
public final class CreateDBAction implements DB {// $FF: synthetic fieldprivate final DB $$delegate_0;public CreateDBAction(@NotNull DB db) {Intrinsics.checkNotNullParameter(db, "db");super();this.$$delegate_0 = db;}public void save() {this.$$delegate_0.save();}
}
3、类委托有什么用?
- 减少委托的代码
- Compose是重委托
CreateDBAction(SqlDB()).save()
CreateDBAction(OracleDB()).save()
属性委托
1、属性委托,委托的是 属性的 set和get
class MyKt{var value = 1314var number by ::value // 两个属性公用get和set
}
// number -> getNumber() -> getValue()
// number = 10 -> setNumber(10) -> setValue(10)
2、委托属性有什么用?
- 字段升级,老字段适配老用户,新字段用于新用户。共用一个get、set
class Database{var data = 941226 // 1.0var newData by ::data // 2.0
}
3、懒加载委托也就是属性委托
- 第一次获取时,才会获取,下面例子第一次获取耗时2秒,其他都立马获得
fun requestDownload(): String{Thread.sleep(2000L)return "sucess"
}// 懒加载,
// 属性委托,委托给
val responseData : String by lazy {requestDownload()
}
// val responseData : String = SynchronizedLazyImpl(requestDownload())
// 借助了SynchronizedLazyImpl的get方法fun main(){println("startloading...")println(responseData)println(responseData)println(responseData)
}
自定义属性委托
1、完全自己实现属性委托
// 自定义委托,定义好get和set之后,属性可以用该类实现属性委托
class Custom{operator fun getValue(owner: Owner, property: KProperty<*>) : String{return "AAA"}operator fun setValue(owner: Owner, property: KProperty<*>, value :String){}
}
class Owner{val responseData : String by Custom()
}
2、利用模板实现属性委托:ReadWriteProperty
// 自定义委托
class Custom2 : ReadWriteProperty<Owner, String>{var str = "default"override fun getValue(thisRef: Owner, property: KProperty<*>): String {return str}override fun setValue(thisRef: Owner, property: KProperty<*>, value: String) {str = value}
}
提供委托/暴露者委托
1、provideDelegate
- 额外的属性初始化逻辑:在属性被委托对象初始化之前进行一些额外的操作,例如数据验证、计算或日志记录等。
- 针对不同属性的不同行为:通过在不同的委托对象的provideDelegate方法中实现不同的逻辑,可以根据属性的不同需求,为每个属性提供不同的行为。
- 属性访问的可扩展性:可以为属性访问添加自定义的行为,例如缓存、延迟加载、权限控制等。
class Owner{val responseData : String by Custom()
}
// 自定义委托
class Custom(var str: String = "Default") : ReadWriteProperty<Owner, String>{override fun getValue(thisRef: Owner, property: KProperty<*>): String {return str}override fun setValue(thisRef: Owner, property: KProperty<*>, value: String) {str = value}
}
// provideDelegate,暴露者委托,== 选择器
class SmartDelegator{operator fun provideDelegate(thisRef:Owner, property: KProperty<*>):ReadWriteProperty<Owner, String>{return if(property.name.isEmpty()){Custom("empty")}else{Custom("normal")}}
}
实战场景
自己实现by lazy
class LazyInitDelegate<T> {private var initializer: (() -> T)? = nulloperator fun getValue(thisRef: Any?, property: KProperty<*>): T {return initializer?.invoke() ?: throw IllegalStateException("Property not initialized")}operator fun setValue(thisRef: Any?, property: KProperty<*>, value: (() -> T)) {initializer = value}
}class Example {val lazyProperty: String by LazyInitDelegate {// 在第一次访问属性时执行初始化逻辑println("Initializing lazy property")"Lazy Initialized"}
}fun main() {val example = Example()println(example.lazyProperty) // 输出:Initializing lazy property \n Lazy Initialized
}
属性委托的日志记录
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KPropertyclass LoggingDelegate<T> {operator fun getValue(thisRef: Any?, property: KProperty<*>): T {val value = property.getter.call()println("Property ${property.name} is accessed, value: $value")return value as T}operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {println("Property ${property.name} is set with value: $value")(property as KMutableProperty).setter.call(thisRef, value)}
}class Example {var property: String by LoggingDelegate()
}fun main() {val example = Example()example.property = "New value" // 输出:Property property is set with value: New valueprintln(example.property) // 输出:Property property is accessed, value: New value \n New value
}
viewmodel
1、如何做到属性内部可以修改,外部不可以修改?
class Data{var data:String = ""private setprivate void changeData(value:String){data = value}
}
val data = Data()
data.data = "" // xxx 不可以
println(data.data) // 可以
2、如何做到kotlin的list集合,对内可以修改,对外界不可以修改
class MyKt{// 内部可以修改private val _data : MutableList<String> = mutableListOf()// 外部不可以修改val data : List<String> by :: _data
}
3、使用::用官方自定义委托,不使用需要自定义委托
4、用委托实现ViewModel的自动构造
class MyViewModel : ViewModel() {}fun main() {// 委托实现val mainViewModel : MyViewModel by viewModels()
}private fun MainActivity.viewModels() : ReadOnlyProperty<MainActivity?, MyViewModel> =object : ReadOnlyProperty<MainActivity?, MyViewModel>{override fun getValue(thisRef: MainActivity?, property: KProperty<*>): MyViewModel {// thisRef永远为nullreturn ViewModelProvider(this@viewModels).get(MyViewModel::class.java)}}
委托TextView:类似DataBinding
//
operator fun TextView.provideDelegate(value: Any?, property: KProperty<*>) =object: ReadWriteProperty<Any?, String?>{override fun getValue(thisRef: Any?, property: KProperty<*>): String? {return text as String}override fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {text = value}}// 创建TextView控件,双向绑定
var textView : TextView = findViewById(R.id.tv)
var message:String ? by textViewtextView.text = "更改了控件的text -> message中的数值也会变"message = "更改了数据 -> 更新UI"
双向绑定,多个控件操作数据
var data1 : String by textView1
var data2 : String by textView2
var data3 : String by textView3data3 = data2
data2 = data1
data1 = "我在吃饭哦"
// 操作数据,View就会变,不用管UI刷新数据
出题目:如何手动实现String的代理(局部变量)?(用扩展函数)
var s1 = "wch"
var s2 : String by ::s1 // 类的成员变量才可以
var s3 : String by s1 // 不用官方的::fun main() {var s1 = "wch"var s2:String by s1 // 报错
}
// Kotlin反射机制
operator fun String.setValue(item: Any?, property: KProperty<*>, value:String){// import kotlin.reflect.jvm.javaField, 已经被移除// property.javaField?.isAccessible = true// property.javaField?.set(item, value)
}
operator fun String.getValue(item: Any?, property: KProperty<*>) = this
相关文章:
Kotlin委托
委托 委托 代理 方法内的成员永远拿不到thisRef:官方委托和自定义委托-》方法里面没办法使用反射 委托只能类委托和属性委托 Kotlin委托 本文链接:https://blog.csdn.net/feather_wch/article/details/132095759 类委托 1、类委托 委托的是接口的方…...
分布式协议与算法——CAP理论、ACID理论、BASE理论
CAP理论 CAP理论,对分布式系统的特性做了高度抽象,比如抽象成了一致性、可用性和分区容错性,并对特性间的冲突(也就是CAP不可能三角)做了总结。 CAP三指标 CAP理论对分布式系统的特性做了高度抽象,形成了…...
接口测试 Jmeter 接口测试 —— 请求 Headers 与传参方式
一、 背景: 在使用 Jmeter 进行接口测试时,有些小伙伴不知道 Headers 和请求参数 (Parameters,Body Data) 的联系,本文主要讲 Content-Type 为 application/x-www-form-urlencoded 和 application/json 的场景。 1、使用 Parame…...
【redis】redis部署1主2从3哨兵demo搭建示例
redis版本为7,搭建的架构为1主2从3哨兵的架构。本文是对搭建的过程做一个回忆,过程可能遗漏了某些步骤,见谅。 首先,需要有一个已经安装了的redis。我们从redis源码目录中,找到一个redis.conf文件,这个文件…...
C++数据结构之平衡二叉搜索树(一)——AVL的实现(zig-zag/左右双旋/3+4重构)
目录 00.BBST——平衡二叉搜索树01.AVL树02.AVL的插入2.1单旋——zig 与 zag2.2插入节点后的单旋实例2.3手玩小样例2.4双旋实例2.5小结 03.AVL的删除3.1单旋删除3.2双旋删除3.3小结 04.34重构05.综合评价AVL5.1优点5.2缺点 00.BBST——平衡二叉搜索树 本文是介绍众多平衡二叉搜…...
免疫疗法勘察兵——DC细胞
DC细胞又叫树状细胞或者树突细胞,1869年由保罗兰格尔翰斯发现,一开始被误以为是神经细胞的一种,直到1973年皮肤科医师Inga Silberberg发现了他的免疫功能,同年,被拉尔夫斯坦曼和赞威尔A科恩两人正式命名为“dendritic…...
Django实现音乐网站 ⑷
使用Python Django框架制作一个音乐网站,在系列文章3的基础上继续开发, 本篇主要是后台歌曲类型表、歌单表模块功能开发。 目录 表结构设计 歌曲类型表结构 歌单表结构 创建表模型 创建表 后台注册表模型 引入表模型 后台自定义 总结 表结构设计…...
2023年华数杯数学建模C题思路 - 母亲身心健康对婴儿成长的影响
# 1 赛题 C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一,她不仅为婴儿提供营养物质和身体保护, 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况,如抑郁、焦虑、 压力等,可能会对婴儿的认知、情…...
openGauss学习笔记-30 openGauss 高级数据管理-别名
文章目录 openGauss学习笔记-30 openGauss 高级数据管理-别名30.1 语法格式30.1.1 列别名语法30.1.2 表别名语法 30.2 参数说明30.3 示例 openGauss学习笔记-30 openGauss 高级数据管理-别名 SQL可以重命名一张表或者一个字段的名称,这个名称为该表或该字段的别名。…...
C#实现多线程局域网扫描器的思路与具体代码
C#实现多线程局域网扫描器的思路与具体代码 思路: 获取局域网内所有 IP 地址遍历所有 IP 地址,使用 Ping 命令测试主机是否在线如果主机在线,则扫描主机上的所有端口,确定哪些端口是开放的输出扫描结果 在上述过程中࿰…...
Redis秒杀:一人一单问题及初步解决
优惠券秒杀一人一单 前言一、需求以及之前存在的问题二、增加一人一单逻辑1.初步代码2.封装一人一单逻辑3.控制锁的粒度 三、事务控制问题四、总结 前言 跟随黑马虎哥学习redis: 这是我认为b站上最好的redis教程,各方面讲解透彻,知识点覆盖…...
python 数据分析面试题:求分组排第n名的记录数据
近期面试遇到一个面试题,分享给大家。 文中会提供详细的解题思路以及问题延伸 一、面试题 面试题:输出各学科总分第一名的学员姓名、年龄、分数数据: class_a {name: [学员1, 学员2, 学员3, 学员4,学员5],age: [23, 24, 26, 27,25],course…...
eclipse常用快捷键
Eclipse常用快捷键 补全代码的声明:alt /快速修复: ctrl 1批量导包:ctrl shift o使用单行注释:ctrl /使用多行注释: ctrl shift /取消多行注释:ctrl shift \复制指定行的代码:ctrl alt down 或…...
什么是OCR?OCR技术详解
光学字符识别(Optical Character Recognition)简称为“OCR”。ORC是指对包含文本资料的图像文件进行分析识别处理,获取文字及版面信息的技术。 一般包括以下几个过程: 1.图像输入 针对不同格式的图像,有着不同的存储格式和压缩方式。目前&…...
【大模型】开源且可商用的大模型通义千问-7B(Qwen-7B)来了
【大模型】开源且可商用的大模型通义千问-7B(Qwen-7B)来了 新闻通义千问 - 7B 介绍评测表现快速使用环境要求安装相关的依赖库推荐安装flash-attention来提高你的运行效率以及降低显存占用使用 Transformers 运行模型使用 ModelScope 运行模型 量化长文本…...
SQL分类及通用语法数据类型
一、SQL分类 DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)DML: 数据操作语言,用来对数据库表中的数据进行增删改DQL: 数据查询语言,用来查询数据库中表的记录DCL: 数据控制语言,用来创建数据库…...
亿欧智库:2023中国功效型护肤产品成分解析研究报告(附下载
关于报告的所有内容,公众【营销人星球】获取下载查看 核心观点 消费端:“纯净美妆〞概念火热,消费驱动因素向成分来源硬核转变 新冠疫情过后,消费者对于生活健康:自然,可持续的关注度持续上升。在消费者…...
Kubernetes高可用集群二进制部署(一)主机准备和负载均衡器安装
Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署(一)主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署(二)ETCD集群部署 Kubernetes高可用集群二进制部署(三)部署…...
python与深度学习(十二):CNN和猫狗大战二
目录 1. 说明2. 猫狗大战的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…...
React(1)——快速入门
目录 一、React背景简介 ❤️ 官网和资料 📚 介绍描述 🐧 React的特点 🔨 React高效的原因 🙏🏻 二、React的基本使用 💻 三、React JSX(JSX:JavaScript XML)📦 …...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...
STM32 低功耗设计全攻略:PWR 模块原理 + 睡眠 / 停止 / 待机模式实战(串口 + 红外 + RTC 应用全解析)
文章目录 PWRPWR(电源控制模块)核心功能 电源框图上电复位和掉电复位可编程电压监测器低功耗模式模式选择睡眠模式停止模式待机模式 修改主频一、准备工作二、修改主频的核心步骤:宏定义配置三、程序流程:时钟配置函数解析四、注意…...
