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

Kotlin带接收者的Lambda介绍和应用(封装DialogFragment)

先来看一个具体应用:假设我们有一个App,App中有一个退出应用的按钮,点击该按钮后并不是立即退出,而是先弹出一个对话框,询问用户是否确定要退出,用户点了确定再退出,点取消则不退出,示例代码如下:

button.setOnClickListener {AlertDialog.Builder(this).setTitle("提示").setMessage("是否要退出应用?").setPositiveButton("确定") { _, _ -> exitApp() }.setNegativeButton("取消", null).show()
}

我们可能经常需要用到对话框,每次都要写很多重复代码,所以就会想要简化一下,比如,首先把链式调用中的 “.” 给去掉,通过使用apply扩展函数,这就是一个带接收者的扩展函数,所以在apply中的接收者this可以省略不写,这样就能不写 “.” 了,如下:

button.setOnClickListener {AlertDialog.Builder(this).apply {setTitle("提示")setMessage("是否要退出应用?")setPositiveButton("确定") { _, _ -> exitApp() }setNegativeButton("取消", null)show()}
}

这里面有一些代码是每次都一模一样的,所以还可以优化,Builder每次都要创建,show()函数每次都要调用,这些可以封装到函数中,如下:

button.setOnClickListener {showDialog(this) { builder ->builder.setTitle("提示").setMessage("是否要退出应用?").setPositiveButton("确定") { _, _ -> exitApp() }.setNegativeButton("取消", null)}
}fun showDialog(context: Context, init: (AlertDialog.Builder) -> Unit) {val builder = AlertDialog.Builder(context)init(builder)builder.show()
}

如上代码所示,我们把Builder的创建和show()方法的调用封装到了方法里面,这样重复的代码就只写一次,不用每次都写了。但是感觉还不是很优雅,每次调用方法都要写 “.”,通过apply可以消除 “.” 的调用,如下:

showDialog(this) { builder ->builder.apply {setTitle("提示")setMessage("是否要退出应用?")setPositiveButton("确定") { _, _ -> exitApp() }setNegativeButton("取消", null)}
}

感觉还是不够优雅,每次都要从builder上调用apply,这也是重复代码,能不能优化成如下这样:

showDialog(this) {setTitle("提示")setMessage("是否要退出应用?")setPositiveButton("确定") { _, _ -> exitApp() }setNegativeButton("取消", null)
}

这就需要用到带接收者的Lambda了,让我们的Lambda接收Builder对象,这样Lambda代码块中默认就有this,这个this对象就是Builder,修改代码如下:

showDialog(this) {setTitle("提示")setMessage("是否要退出应用?")setPositiveButton("确定") { _, _ -> exitApp() }setNegativeButton("取消", null)
}fun showDialog(context: Context, init: AlertDialog.Builder.() -> Unit) val builder = AlertDialog.Builder(context)init(builder)builder.show()
}

OK,这样就完美了,对比showDialog中的参数:

init: (AlertDialog.Builder) -> Unit  // 带参数的Lambda
init: AlertDialog.Builder.() -> Unit // 带接收者的Lambda

从对比上来看,长得差不多,带接收者就是把括号中的参数移到括号前面,并加了一个 “.” ,带 参数 和带 接收者 两种方式能都能实现把Builder的共同代码封装起来,把Builder的不同部分留给调用者设置,但是明显带接收者的Lambda的方式更优雅,带接收者的Lambda还有一点不同,它可像扩展函数那样调用,如下:

fun showDialog(context: Context, init: AlertDialog.Builder.() -> Unit) {val builder = AlertDialog.Builder(context)builder.init()builder.show()
}

如上代码,init是一个Lambda参数的变量名,但是使用时可以像扩展函数一样在接收者Builder的身上直接调用,所以上面代码再结合apply可以简化成一行,如下:

fun showDialog(context: Context, init: AlertDialog.Builder.() -> Unit) {AlertDialog.Builder(context).apply(init).show()
}

啊,这实在是太优雅了,读起来也好理解,对于代码:AlertDialog.Builder(context).apply(init).show(),按顺序理解就行了:创建一个Builder对象,并用init这个LambdaBuilder对象进行初始化,最后调用show进行显示。

总结一下:

  • 无参数的Lambda,调用Lambda时无需传参数,如下:

    val printMessage: () -> Unit = {println("Hello Kotlin")
    }printMessage()
    
  • 带参数的Lambda,调用Lambda时需要传参数,如下:

    val printMessage: (String) -> Unit = { message ->println(message)
    }printMessage("Hello Kotlin")
    

    这里的 message -> 可以省略不写,不写默认参数名为it

  • 带接收者的Lambda,调用Lambda时需要传参数,如下:

    val printMessage: String.() -> Unit = {println(this)
    }
    printMessage("Hello Kotlin")
    

    接收者参数 的区别,我个人感觉功能上是一样的,都是给Lambda使用的一个参数,只不过叫 接收者 的参数有点特别,它在Lambda的代码块中使用this来访问这个参数,而this又是可以省略不写的,基于这个特点,我们不能给带接收者的Lambda起别的参数名,比如下面是错误的,IDE会直接报错:

    val printMessage: String.() -> Unit = { message ->println(message)
    }
    

    如果这样允许的话,那this就不见了,这跟带参数的Lambda就没有区别了,那你为何不直接使用带参数的Lambda呢,所以不允许这样写,带接收者的Lambda就只能用this代表参数,无需多此一举,如果你真的有特殊需求即要用到this,又要同时用到另起一个参数名的话,只能这样:

    val printMessage: String.() -> Unit = {val message = thisprintln(message)println(this)
    }
    

    另外,带接收者的Lambda在调用时可以像扩展函数那样在接收者对象上调用,但是我们知道它实际上就是给Lambda传递了一个this参数,如:

    val printMessage: String.() -> Unit = {val message = thisprintln(message)
    }
    "Hello Kotlin".printMessage() // 等同于:printMessage("Hello Kotlin")
    

现代开发中,显示对话框推荐的做法是使用DialogFragment,但是用了这个感觉变得麻烦了许多,还得先创建一个类继承DialogFragment,如果有多种类型的对话框,那是不是就得创建多个类去继承DialogFragment,以实现多种不同形式?这样做是可以的,但是真的很麻烦,能不能像AlertDialog.Builder那样,一个类就通用,那样多好,学会了带接收者的Lambda后,实现这个功能就太简单了,代码如下:

class MyDialog(private val builder: AlertDialog.Builder) : DialogFragment() {override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {return builder.create()}companion object {fun show(context: Context, fragmentManager: FragmentManager, tag: String, init: AlertDialog.Builder.() -> Unit) {MyDialog(AlertDialog.Builder(context).apply(init)).show(fragmentManager, tag)}fun dismiss(fragmentManager: FragmentManager, tag: String) {(fragmentManager.findFragmentByTag(tag) as? MyDialog)?.dismissAllowingStateLoss()// dismiss()函数在状态保存期间调用会抛异常,比如屏幕旋转时系统会保存界面UI状态,此时调用dismiss()就会抛出异常,// 而调用dismissAllowingStateLoss()则不会抛异常。但是你既然都走到要dismiss的// 地步了,说明不需要对话框了,也不需要系统去恢复了。所以有点搞不懂为什么需要两种取消对话枉的函数}}}

虽然需要声明一个类继承DialogFragment,但是我们只需要声明一次就行,这个类创建对话框时也可以使用AlertDialog.Builder,所以我们通过封装方法把AlertDialog.Builder设置通过带接收者的Lambda交给用户处理即可,使用上也很简单,示例如下:

MyDialog.show(this, supportFragmentManager, "ExitAppTipDialog") {setTitle("提示")setMessage("确定要退出App吗?")setPositiveButton("确定") { dialog, which ->  }setNegativeButton("取消") { dialog, which ->  }
}

这里,对于 “确定” 和 “取消” 按钮也是很常用的,而且不管你是点了确定还是取消,点击之后对话框都会自动取消,所以上面代码中的dialogwhich参数大多数情况下都是用不到的,但是每次都要写也很麻烦,而且函数名setPositiveButtonsetNegativeButton也不好记,常常因为不记得方法名而浪费很多时间去查找方法名,所以我们可以给AlertDialog.Builder增加两个扩展函数来解决这个问题,代码如下:

fun AlertDialog.Builder.setOk(name: String, listener: (() -> Unit)? = null) {setPositiveButton(name) { _, _ -> listener?.invoke() }  
}fun AlertDialog.Builder.setNo(name: String, listener: (() -> Unit)? = null) {setNegativeButton(name) { _, _ -> listener?.invoke() }   
}

当需要显示对话框时代码就简单多了,如下:

MyDialog.show(this, supportFragmentManager, tag) {setTitle("提示")setMessage("确定要退出App吗?")setOk("确定") {  exitApp() }setNo("取消")
}

还能再优化,比如每次要传supportFragmentManager,又长又占空间,它的获取基本上就是从FragmentActivity或者Fragemnt中获取,那就增加重载函数接收这两个类型即可。

还有每次要传tag,早期我们使用AlertDialog的时候也没用过tag啊,所以tag应该可空,当我们没传tag时自动生成一个。示例代码如下:

class MyDialog(private val builder: AlertDialog.Builder) : DialogFragment() {override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {return builder.create()}companion object {private var count = 0fun show(activity: FragmentActivity, tag: String? = null, init: AlertDialog.Builder.() -> Unit) {show(activity, activity.supportFragmentManager, tag, init)}fun show(fragment: Fragment, tag: String? = null, init: AlertDialog.Builder.() -> Unit) {val context = fragment.context ?: returnshow(context, fragment.parentFragmentManager, tag, init)}fun show(context: Context, fragmentManager: FragmentManager, tag: String? = null, init: AlertDialog.Builder.() -> Unit) {val dialogTag = tag ?: "DialogTag_${count++}"MyDialog(AlertDialog.Builder(context).apply(init)).show(fragmentManager, dialogTag)}fun dismiss(fragmentManager: FragmentManager, tag: String) {(fragmentManager.findFragmentByTag(tag) as? MyDialog)?.dismissAllowingStateLoss()}}}fun AlertDialog.Builder.setOk(name: String, listener: (() -> Unit)? = null) {setPositiveButton(name) { _, _ -> listener?.invoke() }
}fun AlertDialog.Builder.setNo(name: String, listener: (() -> Unit)? = null) {setNegativeButton(name) { _, _ -> listener?.invoke() }
}

调用:

MyDialog.show(this) {setTitle("提示")setMessage("确定要退出App吗?")setOk("确定") {  exitApp() }setNo("取消")
}

Ok,事已至此,已经无可挑剔了!

相关文章:

Kotlin带接收者的Lambda介绍和应用(封装DialogFragment)

先来看一个具体应用:假设我们有一个App,App中有一个退出应用的按钮,点击该按钮后并不是立即退出,而是先弹出一个对话框,询问用户是否确定要退出,用户点了确定再退出,点取消则不退出,…...

【NLP】32. Transformers (HuggingFace Pipelines 实战)

🤖 Transformers (HuggingFace Pipelines 实战) 本教程基于 Hugging Face 的 transformers 库,展示如何使用预训练模型完成以下任务: 情感分析(Sentiment Analysis)文本生成(Text …...

[ 设计模式 ] | 单例模式

单例模式是什么?哪两种模式? 单例模式就是一个类型的对象,只有一个,比如说搜索引擎中的索引部分,360安全卫士的桌面悬浮球。 饿汉模式和懒汉模式:饿汉模式是线程安全的,懒汉模式不是线程安全的…...

用网页显示工控仪表

一.起因 现在工控也越来越多的使用web页面来显示电压,电流,温度,转速等物理量.本例使用js控制网页显示速度仪表. 二.代码 <html> <head><script type"text/javascript">var ctx;var px0;var movePoint{x0:0,x1:0};function init(){drawFace();m…...

Spring项目改造Solon版,使用体验,对比

概述 对于Solon有些人可能并不了解&#xff0c;在官方概述中&#xff0c;称其是新一代Java企业级应用开发框架&#xff0c;从零开始构建&#xff0c;有自主的标准规范与开放生态。近16万行代码。 并有更快、更小、更简单的特点 什么样的Java项目用Solon好&#xff1f; 按正常…...

2.CFD 计算过程概述:Fluent在散热计算中的优势

1.主流散热软件 2.电子产品热设计的基本要求 3.失效率与温度之间的关系 4.电子产品热设计的基本要求 5.电子产品必须要做散热设计 6.主动散热与被动散热 7.高效山热方案 8.热交换模型 9.Fluent中传热模型...

【Java ee初阶】多线程(6)

一、阻塞队列 队列的原则&#xff1a;“先进先出”&#xff0c;队列分为普通队列&#xff0c;优先级队列等等。在数据结构中&#xff0c;堆是特殊的完全二叉树&#xff0c;一定不要把堆和二叉搜索树混淆。 阻塞队列是一种特殊的队列&#xff0c;也遵循“先进先出”的原则。 …...

Unity:Surface Effector 2D(表面效应器 2D)

目录 什么是表面效应器 2D&#xff1f; &#x1f3af; 它是做什么的&#xff1f; &#x1f9ea; 从第一性原理解释它是怎么工作的 &#x1f4e6; 重要参数解释 为什么不直接用 Rigidbody&#xff08;刚体&#xff09;来控制运动 &#xff1f; 所以什么时候该用哪个&#…...

Spring 框架的底层原理

Spring 框架的底层原理主要包括以下几个方面&#xff1a; 核心容器&#xff08;IoC 容器&#xff09; IoC&#xff08;控制反转&#xff09;原理 &#xff1a; 依赖注入&#xff08;DI&#xff09; &#xff1a;这是 IoC 的实现方式之一。在传统的程序开发中&#xff0c;程序组…...

【Unity】AssetBundle热更新

1.新建两个预制体&#xff1a; Cube1&#xff1a;GameObject Material1&#xff1a;Material Cube1使用了Material1材质 之后设置打包配置 Cube1的打包配置为custom.ab Material1的打包配置为mat.ab 2.在Asset文件夹下创建Editor文件夹&#xff0c;并在Editor下创建BuildBundle…...

【算法笔记】动态规划基础(二):背包dp

目录 01背包例题状态表示状态计算初始化AC代码 完全背包例题状态表示状态计算初始化TLE代码 多重背包例题状态表示状态计算初始化AC代码 分组背包例题状态表示状态计算初始化AC代码 二维费用背包例题状态表示状态计算初始化AC代码 混合背包问题例题状态表示状态计算初始化TLE代…...

IP属地是我的定位吗?——解析两者区别

在互联网时代&#xff0c;我们经常看到社交媒体、论坛或APP上显示用户的“IP属地”&#xff0c;许多人会疑惑&#xff1a;‌IP属地是不是我的精确定位&#xff1f;它会不会暴露我的隐私&#xff1f;‌ 本文将详细解析IP属地和定位的区别&#xff0c;并解答常见的相关问题&#…...

力扣每日一题1128等价多米诺骨牌对的数量

1128. 等价多米诺骨牌对的数量 题目&#xff1a; 给你一组多米诺骨牌 dominoes 。 形式上&#xff0c;dominoes[i] [a, b] 与 dominoes[j] [c, d] 等价 当且仅当 (a c 且 b d) 或者 (a d 且 b c) 。即一张骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌。 在 0 &l…...

SpringBoot集成CXF框架,实现WebService

SpringBoot官网地址&#xff1a;https://spring.io/projects/spring-ws 1、WebService服务端搭建 Maven依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.17&…...

android-ndk开发(2): macOS 安装 ndk

android-ndk开发(2): macOS 安装 ndk 2025/05/05 1. 概要 对于 android-ndk 在 r23 之前的版本&#xff0c;官方提供了 .zip 文件&#xff0c; 解压即安装。 对于 android-ndk 在 r23 以及之后的版本&#xff0c; 官方只提供了 .dmg 文件&#xff0c; 不能简单的解压完成安…...

科创大赛——知识点复习【c++】——第一篇

目录 输入 一、cin 二、scanf 三、gets 四、getchar 五、fgets 输出 一、cout 二、printf 基本数据类型 一&#xff0c;数据类型有哪些&#xff1f; 二&#xff0c;整型&#xff08;Integer Types&#xff09; 1&#xff0c;修饰符 2&#xff0c;整型数据的数据范…...

硬件工程师面试常见问题(14)

第六十六问&#xff1a;运放--输入偏置电流和输入失调电流 输入偏置电流lb&#xff1a;是由于运放两个输入极都有漏电流的存在。实际的运放,会有电流流入运放的输入端的。那么输入偏置电流就定义这两个电流的平均值。 输入失调电流 Ios&#xff1a;定义为两个差分输入端偏置电…...

Flink流水线任务在线演示

Flink流水线在线演示 1. 登录系统 访问系统登录页面&#xff0c;输入账号密码完成身份验证。 2. 创建任务 入口&#xff1a;通过顶部菜单栏选择 任务开发&#xff0c;或通过快捷入口 快速创建任务。 任务类型&#xff1a;选择 FlinkPipeline。 3. 配置任务 进入配置界面…...

C++笔记之接口`Interface`

C++笔记之接口Interface code review! 一个简洁简短的 C++ 接口实现示例: #include <iostream>// 1. 定义接口(抽象类) class Shape {public:...

css使用aspect-ratio制作4:3和9:16和1:1等等比例布局

文章目录 1. 前言2. 用法2.1 基本语法2.2. 与max-width、max-height等属性结合使用2.3. 动态计算比例 3. 应用场景4. 兼容性和替代方案5. 总结 1. 前言 在网页制作过程中&#xff0c;有时候我们只知道宽度&#xff0c;或者只知道高度&#xff0c;这时候需要制作一个4:3和9:16这…...

深入探索 Apache Spark:从初识到集群运行原理

深入探索 Apache Spark&#xff1a;从初识到集群运行原理 在当今大数据时代&#xff0c;数据如同奔涌的河流&#xff0c;蕴藏着巨大的价值。如何高效地处理和分析这些海量数据&#xff0c;成为各行各业关注的焦点。Apache Spark 正是为此而生的强大引擎&#xff0c;它以其卓越…...

0903Redux改造项目_用户信息_状态管理-react-仿低代码平台项目

文章目录 1 Redux管理用户信息1.1 定义store和reducer1.2 使用useSeletor 2 自定义Hook统一加载用户信息存储Redux3 根据用户登录状态动态跳转页面结语 1 Redux管理用户信息 1.1 定义store和reducer src/store/userReducer.ts代码如下所示&#xff1a; import { createSlice…...

PyTorch_构建线性回归

使用 PyTorch 的 API 来手动构建一个线性回归的假设函数&#xff0c;数据加载器&#xff0c;损失函数&#xff0c;优化方法&#xff0c;绘制训练过程中的损失变化。 数据构建 import torch from sklearn.datasets import make_regression import matplotlib.pyplot as plt i…...

领略算法真谛: 多源bfs

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…...

Linux的web服务器的部署及优化

实验环境的配置 我们依然是要配置本地软件仓库&#xff0c;之前已有详细介绍&#xff0c;然后再次基础上还有如下操作&#xff0c;首先是进入到以下文件进行编辑 编辑内容为下&#xff0c;并且注意自身的网关有没有写错 然后给予权限 再进行下列操作后&#xff0c;就配置完成了…...

ASP.NET Core 请求限速的ActionFilter

文章目录 前言一、实现步骤1&#xff09;创建自定义Action Filter示例1&#xff1a;示例2&#xff1a; 2&#xff09;注册服务3&#xff09;使用 二、实现说明总结 前言 以下是一个基于内存缓存实现的自定义限流Action Filter。 一、实现步骤 1&#xff09;创建自定义Action…...

本地化语音转换工具推荐与使用

软件介绍 Buzz是一款基于OpenAI Whisper技术开发的开源语音转文字工具&#xff0c;支持离线运行和实时语音转换&#xff0c;能够高效完成会议记录、音频转文字等任务。 安装注意事项 在使用Buzz之前需要注意软件的安装设置&#xff0c;由于程序自带较大的模型文件&…...

【心海资源】telegram换U地址完整源码

【心海资源】telegram换U地址完整源码 未测,需要的下载完整的 下载地址&#xff1a;下载地址.txt - 蓝奏云...

神经网络开发实战:从零基础到企业级应用(含CNN、RNN、BP网络代码详解)

简介 神经网络作为深度学习的核心,正在成为现代AI应用的基石。从基础的感知机到复杂的Transformer架构,从图像识别到自然语言处理,神经网络技术的演进推动了人工智能的快速发展。本文将系统介绍神经网络的核心概念、主流模型及其实现原理,并通过三个企业级实战案例(医学图…...

C# WPF 布局

C# 0、WPF 布局 1、ON/OFF按钮 2、textBox 3、ComboBox 4、TabControl 5、Button <Window x:Class"WpfApp5.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/20…...

【PaaS与AI融合】MLOps平台的架构设计

PaaS与AI融合:MLOps平台的架构设计 一、技术背景与发展趋势二、技术架构核心特征1. 全生命周期管理闭环2. 混合编排引擎3. 智能资源调度三、关键技术实现细节1. 持续集成流水线2. 异构资源管理3. 安全治理体系四、行业实践与未来演进典型案例分析发展趋势展望五、架构设计建议…...

硬件工程师面试常见问题(15)

第七十一问&#xff1a;运放增益带宽积解读&#xff08;有待改进&#xff09; 增益带宽积顾名思义&#xff1a;增益&#xff08;就是开环增益&#xff09;与带宽的乘积&#xff1b; 第七十二问&#xff1a;运放输出摆幅 定义&#xff1a;输出摆幅是指输出信号在最大值和最小值…...

SpringMVC——第6章:RESTFul编程风格

一、RESTFul编程风格 1.RESTFul是什么 RESTFul是WEB服务接口的一种设计风格。 RESTFul定义了一组约束条件和规范&#xff0c;可以让WEB服务接口更加简洁、易于理解、易于扩展、安全可靠。 RESTFul对一个WEB服务接口都规定了哪些东西&#xff1f; 对请求的URL格式有约束和规范…...

深度解析:从 GPT-4o“谄媚”到 Deepseek“物理腔”,透视大模型行为模式的底层逻辑与挑战

深度解析&#xff1a;从 GPT-4o“谄媚”到 AI“物理腔”&#xff0c;透视大模型行为模式的底层逻辑与挑战 标签&#xff1a;人工智能, GPT-4o, 大语言模型, AI伦理, 人机交互, 技术思考 大家好&#xff01;最近AI圈最火的“瓜”之一&#xff0c;莫过于OpenAI的GPT-4o模型在一…...

2025 年最新树莓派 Pico 连接 OLED 显示字模汉字详细教程

OLED 概述 OLED&#xff08;Organic Light-Emitting Diode&#xff0c;有机发光二极管&#xff09;是一种基于有机材料的发光技术&#xff0c;通过电流驱动有机薄膜发光&#xff0c;具有自发光、高对比度、柔性可弯曲等特点。 4 针脚 OLED 硬件电路如图所示&#xff0c;GND 接…...

【Ubuntu 安装Docker CE-Jenkins】

安装Docker CE(Ubuntu) Install | Docker Docs官网 使用apt仓库安装 DNS配置(可选) #手动替换 sudo vim /etc/systemd/resolved.conf #典型配置如下 [Resolve] DNS8.8.8.8 DNS114.114.114.114 FallbackDNS1.1.1.1 # 备用 DNS#sed替换 sudo sed -i /^#DNS/ {s/#DNS/DNS8.8.8…...

知识图谱 + 大语言模型:打造更聪明、更可靠的AI大脑 —— 探索 GraphRAG 中文优化与可视化实践

大语言模型&#xff08;LLMs&#xff09;无疑是近年来人工智能领域最耀眼的明星。它们强大的自然语言理解和生成能力&#xff0c;在文本创作、代码生成、对话交互等众多领域展现了惊人的潜力。然而&#xff0c;当前的 LLMs 并非完美无缺&#xff0c;它们常常面临着“幻觉”&…...

三、【LLaMA-Factory实战】模型微调进阶:从LoRA到MoE的技术突破与工程实践

一、引言 在大模型微调领域&#xff0c;选择合适的训练策略直接决定了效率与效果的平衡。LLaMA-Factory深度整合了参数高效微调&#xff08;PEFT&#xff09;、全量微调、混合专家模型&#xff08;MoE&#xff09;等12种训练策略&#xff0c;支持从消费级GPU到多卡集群的全场景…...

Photo-SLAM论文理解、环境搭建、代码理解与实测效果

前言&#xff1a;第一个解耦式Photo-SLAM&#xff0c;亮点和效果。 参考&#xff1a;https://zhuanlan.zhihu.com/p/715311759 全网最细PhotoSLAM的conda环境配置教程&#xff0c;拒绝环境污染&#xff01;&#xff01;-CSDN博客 1. 环境搭建 硬件&#xff1a;RTX 4090D wi…...

解决pycharm检测不到已经装好的conda的pytorch环境

问题 1.找装anaconda的位置&#xff08;我装到了py-anacon下&#xff09; 2.找到下图中的conda.bat 3.pycharm社区版右下角&#xff0c;添加新解释器 4.选conda环境&#xff0c;选择2.中conda.bat的位置&#xff0c;加载环境&#xff0c;使用现有环境&#xff0c;可以看到有选…...

【计算机视觉】3d人脸重建:3DDFA_V2:实时高精度3D人脸重建与密集对齐技术指南

3d人脸重建&#xff1a;3DDFA_V2&#xff1a;实时高精度3D人脸重建与密集对齐技术指南 一、项目概述与技术背景1.1 3DDFA_V2核心价值1.2 技术演进路线1.3 核心技术指标 二、环境配置与模型部署2.1 硬件要求2.2 软件安装基础环境搭建关键组件安装 2.3 模型下载 三、核心算法原理…...

谈判模拟器 - Gemini 2.5 商业优化版

核心目标&#xff1a; 基于深厚的理论知识、丰富的实战经验和前沿的技术洞察&#xff0c;结合麦肯锡领先的谈判策略框架&#xff0c;为用户提供全面、深入、可操作的商业谈判策略指导和建议&#xff0c;助力其在复杂商业环境中达成最优谈判结果&#xff0c;并实现商业价值最大化…...

深度学习系统学习系列【4】之反向传播(BP)四个基本公式推导

文章目录 补充知识&#xff1a;∇ 和 ⊙ 运算符详解∇ (nabla) 运算符⊙ (圆圈点) 运算符 反向传播基本公式计算图和基本定义BP1&#xff1a;输出层误差推导BP1公式的重要性实际例子BP2第 l l l层误差推导BP3 &#xff1a;损失函数关于偏置(b)偏导的推导BP4&#xff1a; 损失函…...

算法每日一题 | 入门-顺序结构-上学迟到

上学迟到 题目描述 学校和 yyy 的家之间的距离为 s 米&#xff0c;而 yyy 以 v 米每分钟的速度匀速走向学校。 在上学的路上&#xff0c;yyy 还要额外花费 10 分钟的时间进行垃圾分类。 学校要求必须在上午 8:00 到达&#xff0c;请计算在不迟到的前提下&#xff0c;yyy 最…...

开源库测试

yolov10 https://github.com/THU-MIG/yolov10 conda create -n yolov10 python3.9 conda activate yolov10 pip install -r requirements.txt pip install -e .报错 找不到对应版本 Could not find a version that satisfies the requirement gradio4.31.5 (from versions:…...

因为gromacs必须安装cuda(系统自带的NVIDIA驱动不行),这里介绍下如何安装cuda

1. 安装步骤 查看是否安装了cuda # 法1 cat /usr/local/cuda/version.txt # 法2 nvcc --version 若没有安装&#xff0c;则查看是否有N卡驱动&#xff0c;若无N卡驱动&#xff0c;则到软件与更新 -> 附加驱动中安装驱动 查看N卡驱动支持的cuda版本 nvidia-smi 如下…...

ABC 404

1.C 题&#xff1a; 1.思路&#xff1a; NM&每个点读数为2&#xff0c;但图中有可能出现多环&#xff0c;需要判断所有点是否都在同一连通块上&#xff0c;有俩种解法&#xff1a;搜索&#xff0c;循环 2.代码&#xff08;循环做法&#xff09; #include<bits/stdc.h&g…...

机器学习朴素贝叶斯算法

1.朴素贝叶斯算法 1.1基本概念 其分类原理是利用贝叶斯公式根据某特征的先验概率计算出其后验概率&#xff0c;然后选择具有最大后验概率作为该特征所属的类。之所以称之为“朴素”&#xff0c;是因为贝叶斯分类只做最原始、最简单的假设&#xff1a;所有的特征之间是相对独立…...

Linux:深入理解数据链路层

实际上一台主机中&#xff0c;报文并没有通过网络层直接发送出去&#xff0c;而是交给了自己的下一层协议——数据链路层&#xff01;&#xff01; 一、理解数据链路层 网络层交付给链路层之前&#xff0c;会先做决策再行动&#xff08;会先查一下路由表&#xff0c;看看目标网…...

健康养生:从生活点滴启航

养生并非遥不可及的高深学问&#xff0c;只需把握生活中的细微之处&#xff0c;就能为健康保驾护航。 清晨睁眼&#xff0c;先在床上做简单的搓脸动作&#xff0c;从下巴到额头轻柔按摩&#xff0c;促进面部血液循环&#xff0c;唤醒肌肤活力。随后空腹喝一杯温水&#xff0c;可…...