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

Unity/C#------委托与事件(一篇文章彻底搞懂...)

一:委托

        所有的代码语言创造者母语都是英语,我们从英语翻译到中文的过程中难免会存在一些不太能还原本意的词,比如我之前一直不理解构造函数和析构函数,只知道这俩货作用相反,直到我看到了它的英文意思,Construstor/Distructor,我才彻底理解了他们的作用。

        接下来我们来看委托,Delegate,来看两个例句,深入理解Delegate...

Can you delegate some tasks or projects?                                你能够分配一些任务或者项目吗?

So why not delegate more work to your employees?    所以你为啥不给你的员工多分分配点任务?

从上面的句子中我们可以看到,他就是分配,也就是委托的意思(但是感觉可能有些人对委托的理解不如分配来的直接,至少对我来说是这样)

微软官方的解释是委托可以获取一个或多个方法,但是类型和返回值必须和方法相同,可以理解成委托是方法的抽象,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。这点和函数指针很像...后续写单播委托时候再添加这部分内容。

我们可以说,委托就是一个方法的类型

话不多说,看代码...

一、单播委托——一次只能装进去一个方法

Public delegate 返回值 MyDelegate(参数1,参数2)

就这么一步,我们就把委托定义出来了,接下来要做的就是把这玩意儿实例化出来,那我们怎么把我们的方法给委托呢?

第一点就是我们需要有和定义的委托类型一致的返回值和参数列表

其实委托就是起源于C语言的函数指针,不过在C#以委托的形式存在了

但是在Java中没有委托这么一说...

//使用Typedef将该函数指针声明为一种类型,它是指向两个参数为int,返回值为int的函数指针
typedef int (*Calculator)(int x , int y);int Add(int a ,int b)
{return a+b;
}int Multiply(int a ,int b)
{return a*b;
}//函数指针的使用Calculator Pointer1 = &Add;
Calculator Pointer2 = &Multiply;//这样我们在调用函数的时候就不再写函数,而是采用函数指针的方法,间接的指向了该类型的函数
Pointer1(0,1);
Pointer2(1,2);

从上面的函数指针我们可以看出,我们在注册方法的时候,可以间接的声明一个和该方法类型和返回值都一致的指针类型,从而调用函数指针即可,那么我们的委托和它是类似的....

接下来看我们的委托的实例化和方法的插入,可以使用new,也可以直接引用方法:

//实例化委托
MyDelegate myDelegate = new MyDelegate(Function);//简化写法
myDelegate = Telegate;返回值类型 Function(参数1,参数2)
{方法体;
}

委托的调用,可以使用Invoke,也可以直接写委托名+()

可以通过Invoke进行调用委托
myDelegate.Invoke();也可以直接myDelegate();

二、多播委托——一次装多个方法,但不安全

在上面的方法添加环节,我们只需要做小小的修改

myDelegate += ChangeColor;
myDelegate += Log;

但是其实我们没事儿也不会这么干,这样长期下来有可能会存在内存泄漏,如果顺序执行列表中方法有一个出错了,后面的就都不会执行了,所以我们还有其他更好的选择

三、Action委托和Func委托

大多数的情况下,我们不太需要自己去声明委托,而是使用现成的委托即可,Unity为我们内置了两种泛型委托

1)Action委托——返回值必须为空,参数可有可无

//声明无参数的Action委托
Action action;//声明有参数的Action委托
Action<string,float> action1;//Action的使用
action = new Action(同参数的方法1)
action1 = new Action<string ,float> (sayhello);//sayhello方法
public void SayHello(string name,float num)
{Debug.log(sting.Fromat("{0} has {1} ChampionShips .",name,num));
}

2) Func委托——返回值必须有,但是参数可有可无

//声明Func委托,前面是参数,后面是返回值
Func<double,double,double> func1;//使用
func1 = new Func<double,double,double>(Add);//跟Func结构一样的方法
public double Add(doublea ,double b)
{return a+b;
}

二:事件

事件,使对象或类具备通知能力

事件,是委托字段的一个包装器,它对于委托字段的访问起了限制作用

对外界隐藏了委托实例的大部分功能,仅暴露添加/移除事件处理器的功能

日常开发中,自己声明事件的机会比较少,一般是用已有事件比较多...

java中没有委托,事件这么一说,只用Interface来实现

一、事件的五个重要因素

事件的拥有者

事件成员(Event)

事件的响应者(Event Subscriber)

事件处理器(Event handler,本质上是回调方法)

事件订阅(+=)

他们之间的关系可以如下几种:

1:事件的拥有者类和事件的响应者是不同的类

using System.Timers;
using UnityEngine;public class EventTimothyLiu1 : MonoBehaviour
{private void Start(){//世间间隔,每过1s就触发Elesap事件Timer timer = new Timer();timer.Interval = 1000;Boy boy = new();Girl girl = new();timer.Elapsed += boy.OnAction;timer.Elapsed += girl.OnAction;timer.Start();}
}
public class Boy
{internal void OnAction(object sender, ElapsedEventArgs e){Debug.Log("1");}
}
public class Girl
{internal void OnAction(object sender, ElapsedEventArgs e){Debug.Log("2");}
}

在该示例中,事件的拥有者是Timer类,事件的响应者是自定义的Boy,Girl类

所以事件的响应者和拥有者是两个类

第二个例子:

using System;
using System.Windows.Forms;namespace EventLiu
{class Program{static void Main(string[] args){//事件的拥有者:FormForm form = new Form();//事件的响应者:ControllerController controller = new Controller(form);form.ShowDialog();}}class Controller{private Form form;/// <summary>/// CTOR再加Tab即可编写出构造器/// 也叫构造函数,每个类都必须有/// 在构建类的引用时自动运行的方法!/// </summary>public Controller(Form form){if (form!= null){//this就是类的实例//this后是我们定义的字段,后面是参数formthis.form = form;//Click是事件this.form.Click += this.FormClicked;}}/// <summary>/// 事件处理器/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void FormClicked(object sender, EventArgs e){this.form.Text = DateTime.Now.ToString();}}
}

上述的代码段中,我们引入了Form名称空间

事件的拥有者是Form,事件的响应者是Controller

2:事件的拥有者同时也是事件的响应者

using System;
using System.Windows.Forms;namespace EventLiu
{class Program1{static void Main(string[] args){//事件的拥有者:myForm//事件的接受者:myFormMyForm myForm = new MyForm();//事件:ClickmyForm.Click += myForm.FormClicked;}}/// <summary>/// 继承Form/// </summary>class MyForm : Form{/// <summary>/// 事件的处理器/// </summary>/// <param name="sender"></param>/// <param name="e"></param>internal void FormClicked(object sender, EventArgs e){this.Text = DateTime.Now.ToString();}}
}

事件的拥有者是Form

事件的响应者也是myForm的实例

3:事件的拥有者是事件的响应者的成员(频率最高)

事件的响应者用自己的方法订阅者自己的字段成员的事件

using System;
using System.Windows.Forms;namespace EventLiu
{class Program1{static void Main(string[] args){MyForm myForm = new MyForm();myForm.ShowDIalog();}}class MyForm :Form{private TextBox textBox;//从订阅看事件拥有者就是buttonprivate Button button;public MyForm(){this.textBox = new TextBox();this.button = new Button();this.Controls.Add(this.button);this.Controls.Add(this.textBox);//Click是事件//事件的响应者是this,也就是MyForm的实例对象this.button.Click += this.ButtonClicked;}//事件处理器private void ButtonClicked(object sender, EventArgs e){this.textBox.Text = "Hello";}}
}

在该段代码中,我们自己创建MyForm类,继承自Form

事件的拥有者是该类中的成员Button,事件的响应者是该类的实例化

也就是儿子有事件,爸爸订阅了。                                                                                                                                           

                                                                                                                                                                                                                                                                                 

4:事件的响应者是事件的拥有者的成员

二、事件的完整声明格式

用以下代码来看:

using System;
using System.Threading;
using UnityEngine;public class EventTimothyLiu2 : MonoBehaviour
{private void Start(){Customer1 customer1 = new();Waiter1 waiter1 = new();customer1.Order += waiter1.Action;customer1.Action();customer1.PayTheBill();}
}
/// <summary>
/// 派生自EventArgs,习惯
/// </summary>
public class OrderEventArgs1:EventArgs
{public string DishName { get; set; }public string size { get; set; }
}//把委托放置在类外
/// <summary>
/// 用EvenetHandler原因:
/// 1:别人看到这个后缀就知道这个委托是专门用来声明事件的
/// 2:EventHandle表明委托来约束事件处理器
/// 3:委托的实例是用来存储事件处理器
/// </summary>
/// <param name="customer"></param>
/// <param name="e"></param>
public delegate void OrderEventHandler1(Customer1 customer, OrderEventArgs1 e);/// <summary>
/// Customer1是事件的拥有者,它拥有事件Order
/// </summary>
public class Customer1
{private OrderEventHandler1 OrderEventHandler1;public event OrderEventHandler1 Order{add { this.OrderEventHandler1 += value; }remove { this.OrderEventHandler1 -= value; }}public double Bill { get; set; }public void PayTheBill(){Debug.Log("I will pay $" + this.Bill);}public void WalkIn(){Debug.Log("Walk into the restaurant.");}public void SitDown(){Debug.Log("Sit down.");}public void Think(){for (int i = 0; i < 5; i++){Debug.Log("Let me think...");Thread.Sleep(1000);}if(this.OrderEventHandler1 != null){OrderEventArgs1 e = new OrderEventArgs1{DishName = "Kongpao Chicken",size = "large"};this.OrderEventHandler1.Invoke(this,e);}}public void Action(){this.WalkIn();this.SitDown();this.Think();}
}/// <summary>
/// Waiter1是事件的接受者,它拥有事件的响应器Action
/// </summary>
public class Waiter1
{public void Action(Customer1 customer1, OrderEventArgs1 e){Debug.Log("I will serve you  the dish -{0} "+ e.DishName);double price = 10;switch (e.size){case "small":price = price * 0.5;break;case "large":price = price * 1.5;break;default:break;}customer1.Bill += price;}
}

从以上代码可以看出

Customer进入餐厅,走进,坐下,思考,然后触发点餐事件

Customer是点餐事件的拥有者

Waiter是点餐事件的接受者,它还得有点餐的响应事件,就是算出价格,并采取行动

在自定义点餐事件的时候,我们采用了EventHandler委托来给事件做支撑

创建了EventArgs类来承载事件,谁发起的事件,谁就是委托的第一个参数

但是这样写比较复杂,我们来看事件的简略声明格式

三、事件的简单声明格式

using System;
using System.Threading;
using UnityEngine;public class EventTimothyLiu3 : MonoBehaviour
{private void Start(){Customer2 customer2 = new();Waiter2 waiter2 = new Waiter2();customer2.Order2 += waiter2.Action;customer2.Action();customer2.PayTheBill();}
}
/// <summary>
/// 先声明委托,委托两个参数分别是事件的拥有者和事件需要使用的参数
/// </summary>
/// <param name="customer2"></param>
/// <param name="e"></param>
public delegate void OrderEventHandler2(Customer2 customer2, OrderEventArgs2 e);/// <summary>
/// 容纳事件参数
/// </summary>
public class OrderEventArgs2:EventArgs
{public string DishName { get; set; }public string size { get; set; }
}/// <summary>
/// 事件的拥有者
/// </summary>
public class Customer2
{//原本需要先实例化委托,然后将委托赋予事件中进行使用//private OrderEventHandler1 OrderEventHandler1;//public event OrderEventHandler1 Order//{//    add { this.OrderEventHandler1 += value; }//    remove { this.OrderEventHandler1 -= value; }//}//现在进行简化/// <summary>/// 只需要事件+委托即可/// </summary>public event OrderEventHandler2 Order2;public double Bill { get; set; }public void PayTheBill(){Debug.Log("I will pay $ " + this.Bill);}public void WalkIn(){Debug.Log("I'm Coming");}public void SitDown(){Debug.Log("I'm sit down");}public void Think(){for (int i = 0; i < 5; i++){Debug.Log("Let me think..");Thread.Sleep(1000);}if(Order2 != null){OrderEventArgs2 e = new OrderEventArgs2();e.DishName = "Kongpao Chicken";e.size = "large";this.Order2.Invoke(this, e);}}public void Action(){this.WalkIn();this.SitDown();this.Think();}
}
/// <summary>
/// 事件的接收者和Action事件
/// </summary>
public class Waiter2
{public void Action(Customer2 customer2, OrderEventArgs2 e){Debug.Log("I will serve you  the dish: " + e.DishName);double price = 10;switch (e.size){case "small":price = price * 0.5;break;case "large":price = price * 1.5;break;default:break;}customer2.Bill += price;}
}

还是上述的代码,我们进行了简化

我们将如下代码:

private OrderEventHandler1 OrderEventHandler1;public event OrderEventHandler1 Order{add { this.OrderEventHandler1 += value; }remove { this.OrderEventHandler1 -= value; }}

简化成了:

public event OrderEventHandler2 Order2

这样的简化是微软后台进行了,我们可以直接如此书写

其实并非不存在委托字段的声明,还是存在的,只是存在于后台中,微软后台声明了,我们不需要看到,所以可以进行简化

还可以进一步简化:

将声明委托的部分省略掉,即使用微软定义好的EventHandler的委托类型,代码如下:

using System;
using System.Threading;
using UnityEngine;public class EventTimothyLiu4 : MonoBehaviour
{private void Start(){Customer3 customer3 = new Customer3();Waiter3 waiter3 = new Waiter3();customer3.Order3 += waiter3.Action;customer3.Action();customer3.PayTheBill();}
}
public class OrderEventArgs3:EventArgs
{public string DishName { get; set; }public string size { get; set; }
}
public class Customer3
{public event EventHandler Order3;public double Bill { get; set; }public void WalkIn(){Debug.Log("Im coming");}public void SitDown(){Debug.Log("Im Sitting");}public void Think(){for (int i = 0; i < 5; i++){Debug.Log("Im thinking");Thread.Sleep(1000);}if(Order3 != null){OrderEventArgs3 e = new OrderEventArgs3();e.DishName = "KongpaoChicken";e.size = "large";this.Order3.Invoke(this, e);}}internal void Action(){this.WalkIn();this.SitDown();this.Think();}internal void PayTheBill(){Debug.Log("I will Pay for $" + this.Bill);}
}
public class Waiter3
{public void Action(object sender,EventArgs e){Customer3 customer3 = sender as Customer3;OrderEventArgs3 orderinfo = e as OrderEventArgs3;Debug.Log("i will serve  you the dish" + orderinfo.DishName);double price = 10;switch (orderinfo.size){case "small":price = price * 0.5;break;case "large":price = price * 1.5;break;default:break;}customer3.Bill += price;}
}

注意在Waiter类中的实例化Cutsome3和OrderEventArgs3的实例化使用

采用实例化,参数 as 的方法,将参数转化为我们需要的

为什么有了委托字段/属性,还需要事件?

为了程序逻辑更加有道理,更加安全,谨防“借刀杀人”

三:UnityEvent/UnityAction

相关文章:

Unity/C#------委托与事件(一篇文章彻底搞懂...)

一&#xff1a;委托 所有的代码语言创造者母语都是英语&#xff0c;我们从英语翻译到中文的过程中难免会存在一些不太能还原本意的词&#xff0c;比如我之前一直不理解构造函数和析构函数&#xff0c;只知道这俩货作用相反&#xff0c;直到我看到了它的英文意思&#xff0c;Con…...

别再为 Jenkins 安装烦恼,Docker 帮你轻松解决

前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文收录与云原生相关的专栏&#xff0c;以下是我的简介&#xff1a; &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是沐风晓月&#xff0c;双…...

汇编语言程序设计(一)

前言 在学习汇编语言之前&#xff0c;我们应该要知道汇编语言他是一门怎么样的语言。汇编语言是直接工作在硬件上的一门编程语言&#xff0c;学习汇编语言之前最好先了解一下计算机硬件系统的结构和工作原理。学习汇编语言的重点是学习如何利用硬件系统的编程结构和指令集进而…...

【uni-app教程】四、UniAPP 路由配置及页面跳转

四、UniAPP 路由配置及页面跳转 (1) 路由配置 uni-app页面路由为框架统一管理&#xff0c;开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同&#xff0c;如仍希望采用 Vue …...

ROS从入门到精通系列(二十八)-- ROS控制器图形化界面开发

ROS (Robot Operating System, 机器人操作系统) 作为机器人软件中的通信及控制中间件,提供一系列程序库和工具以帮助软件开发者创建机器人应用软件。它提供了硬件抽象、设备驱动、函数库、可视化工具、消息传递和软件包管理等诸多功能。ROS遵循BSD开源许可协议。 随着机器人智…...

Submodule命令:android如何将自己项目中的某个Module作为gitlab中第三方公共库

一、创建远程公共库 1、Android Studio创建本地仓库 创建一个新的module 在新建module中添加代码(此处示例代码) 右击新建的module&#xff0c;打开新建module的命令行界面&#xff0c; 因为我们只上传这个module的代码&#xff0c;而不是整个项目的代码 命令行中输入以下命令…...

MySQL索引事务

1.索引1.1概念索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c;并指定索引的类型&#xff0c;各类索引有各自的数据结果实现。&#xff08;这里只用通俗的语言和图片进行介绍&#xff09;1.2作用数据库中的表…...

ISO27001信息安全管理体系认证

​ISO信息安全管理体系认证 一、什么是ISO信息安全管理体系认证&#xff1f; ISO是信息安全管理体系认证&#xff0c;是由国际标准化组织&#xff08;ISO&#xff09;采纳英国标准协会BS-2标准后实施的管理体系&#xff0c;成为了“信息安全管理”的国际通用语言&#xff0c;企…...

Linux应用GUI开发C++ 之gtkmm4(1)

目录概述GTKgtkmm安装gtkmm4hello,worldcodelite配置代码解释概述 GTK GTK是一个小部件工具包。GTK创建的每个用户界面都由小部件组成。这是在C语言中使用GObject实现的&#xff0c;GObject是一个面向对象的C语言框架。窗口小部件是主容器。然后通过向窗口中添加按钮、下拉菜…...

选课系统的设计与实现

技术&#xff1a;Java等摘要&#xff1a;目前国内各高校的规模越来越大&#xff0c;进而造成教师教学管理等工作量日趋加大。然而&#xff0c;现代教育的信息化、网络化已经成为教育发展的一个重要方向&#xff0c;同时也为解决高校教学管理效率低下的现状&#xff0c;使管理突…...

关于安卓的一些残缺笔记

安卓笔记Android应用项目的开发过程Android的调试Android项目文档结构Intent的显式/隐式调用Activity的生命周期1个Activity界面涉及到生命周期的情况2个Activity界面涉及到生命周期的情况Android布局的理论讲解Activity界面布局ContentProvider是如何实现数据共享Android整体架…...

MySQL 中的锁有哪些类型,MySQL 中加锁的原则

锁的类型MySQL 找那个根据加锁的范围&#xff0c;大致可以分成全局锁&#xff0c;表级锁和行级锁。全局锁全局锁&#xff0c;就是对整个数据库加锁。加锁flush tables with read lock解锁unlock tables全局锁会让整个库处于只读状态&#xff0c;之后所有的更新操作都会被阻塞&a…...

Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作

场景 Sqlite数据库 SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。 就像其他数据库&#xff0c;SQLite 引擎不…...

2023最新版本RabbitMQ下载安装教程

一、RabbitMQ简介 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。主要用于在进程、应用程序和服务器之间交换数据&#xff0c;可以通过插件支持进行扩展&#xff0c;支持许多协议&#xff0c;并提供高性能、可靠性、集群和高可用队列。 AMQP &#xff1a;Advanced Me…...

如何使用码匠连接 Elasticsearch

目录 在码匠中集成 Elasticsearch 在码匠中使用 Elasticsearch 关于码匠 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;常用于处理大规模数据集的搜索、实时数据分析和数据挖掘任务。它支持多种数据源&#xff0c;包括关系型数据库&#xff08;如 MySQL、Pos…...

jmeter学习笔记二(jmeter函数与后置处理器)

Jmeter重要的函数 ${__counter(,)} 计数器 ​ ${__counter(TRUE,)} 默认加1; TRUE&#xff0c;每个用户有自己的计数器&#xff1b;FALSE&#xff0c;使用全局计数器 ​ 计数器元件&#xff0c;可以设置起始值&#xff0c;间隔值&#xff0c;最大值。运行结果超过最大值时&a…...

【独家】华为OD机试提供C语言题解 - 子序列长度

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明子序…...

Java之注解

注解1.1 注解的概念1.2 内置注解1.3 元注解1.4 自定义注解1.1 注解的概念 Annotation 是从JDK5.0 开始引入的新技术 Annotation的作用&#xff1a; 不是程序本身&#xff0c;可以对程序做出解释&#xff08;这一点和注释comment没什么区别&#xff09;可以被其他程序&#xff…...

【C++】string

【C修炼秘籍】string 目录 【C修炼秘籍】string 文章目录 前言 一、标准库里的string 二、string常用接口功能简介&#xff08;具体使用和底层转到模拟实现&#xff09; 1、string类的常见构造函数 2、string类对象的容量操作 3、string类对象的访问及遍历操作 4、 string类对象…...

JVM详解——执行引擎

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;耶瞳空间 一&#xff1a;执行引擎介绍 “虚拟机”是一个相对于“物理机”的概念&#xff0c;这两种机器都有代码执行能力&#xff0c;其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和…...

2026届学术党必备的六大降重复率平台推荐榜单

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 令AI精确执行任务的基础&#xff0c;是下达精准的指令&#xff0c;此即降AI指令。降AI指令专…...

重塑游戏社交:Nucleus Co-Op如何用一台电脑创造四人同屏体验

重塑游戏社交&#xff1a;Nucleus Co-Op如何用一台电脑创造四人同屏体验 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 问题&#xff1a;本地多人…...

3分钟掌握完全离线的实时语音转文字:TMSpeech让你彻底告别云端依赖

3分钟掌握完全离线的实时语音转文字&#xff1a;TMSpeech让你彻底告别云端依赖 【免费下载链接】TMSpeech 腾讯会议摸鱼工具 项目地址: https://gitcode.com/gh_mirrors/tm/TMSpeech 在数字时代&#xff0c;语音转文字已成为现代办公和学习的高效助手&#xff0c;但你是…...

Encounter/Innovus GIFT TCL 脚本流程索引清单

目录 一、 布局阶段 (Placement) 二、 布线阶段 (Routing) 三、 时序阶段 (Timing) 四、 电源阶段 (Power) 五、 IO 与端口处理 六、 调试与辅助工具 一、 布局阶段 (Placement) 脚本名称 核心用途 调用场景 userAddAllHInsts.tcl 为源模块中的每个扇出添加缓冲器 解决高扇…...

CipherChat:基于词元替换的端到端加密大模型对话方案解析

1. 项目概述&#xff1a;当大模型对话遇上密码学最近在折腾大语言模型&#xff08;LLM&#xff09;应用开发的朋友&#xff0c;可能都遇到过同一个头疼的问题&#xff1a;如何保证用户和模型之间对话的隐私和安全&#xff1f;我们辛辛苦苦搭建的智能客服、个人助理或者创意写作…...

现代差旅电力管理实战:从充电安全到设备续航全攻略

1. 一次久违的飞行&#xff1a;无处不在的电力焦虑与科技依赖距离上一次飞行已经过去了整整十七个月。当我上周踏入纽约拉瓜迪亚机场&#xff0c;准备开启后疫情时代的首次旅程时&#xff0c;感觉像是进入了另一个维度。在我缺席的这段时间里&#xff0c;LGA完成了一场彻底的蜕…...

动物森友会岛屿设计终极指南:用Happy Island Designer轻松规划你的梦想岛屿

动物森友会岛屿设计终极指南&#xff1a;用Happy Island Designer轻松规划你的梦想岛屿 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)"&#xff0c;是一个在线工具&#xff0c;它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会…...

从布朗运动到伊藤公式:金融随机世界的建模基石

1. 从花粉运动到股票价格&#xff1a;布朗运动的金融启示 1827年&#xff0c;英国植物学家罗伯特布朗在显微镜下观察到花粉颗粒在水中的不规则舞动&#xff0c;这个看似简单的物理现象却在80年后被爱因斯坦用数学语言精确描述。有趣的是&#xff0c;当我们将显微镜换成股票行情…...

利用taotoken模型广场为ai应用快速进行模型选型与测试

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 利用Taotoken模型广场为AI应用快速进行模型选型与测试 在构建一个需要集成多种AI能力的应用时&#xff0c;开发者面临的首要挑战往…...

GitHub 代码提交常见问题及解决指南

摘要本文聚焦 GitHub 代码提交流程&#xff0c;围绕本地文件上传、远程仓库关联、分支推送等核心操作&#xff0c;梳理常见报错&#xff08;如可疑所有权、分支不匹配、协议不支持等&#xff09;&#xff0c;解析错误成因并提供分步解决方法&#xff0c;覆盖 Git 命令执行、仓库…...