c# 委托 事件 lambda表达式

委托

C/C++中的函数指针实例:

typedef int (*Calc)(int a, int b); //这里必须加括号
int Add(int a, int b)
{return a + b;
}
int Sub(int a, int b)
{return a - b;
}
int main()
{int x = 100;int y = 200;int z = 0;Calc funcPoint1 = &Add;Calc funcPoint2 = &Sub;z = funcPoint1(x, y);cout << z << endl;z = funcPoint2(x, y);cout << z << endl;
}

委托实例

class Program{static void Main(string[] args){Calculator c = new Calculator();//Action委托:没有返回参数Action action = new Action(c.PrintInfo);c.PrintInfo();action.Invoke();action();//Func委托:有返回参数Func<int, int, int> f = new Func<int, int, int>(c.Add);Func<int, int, int> f2 = new Func<int, int, int>(c.Sub);Console.WriteLine(f(1, 2));Console.WriteLine(f.Invoke(1, 2));Console.WriteLine(f2(1, 2));Console.WriteLine(f2.Invoke(1, 2));}}class Calculator{public void PrintInfo(){Console.WriteLine("this class has 3 methods");}public int Add(int a, int b){return a + b;}public int Sub(int a, int b){return a - b;}}
class Program
{static void Main(string[] args){Action<string> action = new Action<string>(SayHello);action("Tim");}static void SayHello(string name){Console.WriteLine($"Hello, {name1}!");}
}
//可以用var关键字来缩短代码:
class Program
{static void Main(string[] args){var action = new Action<string, int>(SayHello);action("Tim");}static void SayHello(string name, int rount){for(int i=0; i<round; ++i){Console.WriteLine($"Hello, {name1}!");}}
}

Console.WriteLine后面 “$”的作用

//复杂麻烦的写法string str1 = "my name is " + name + ",my age is " + age + ".";//使用Format的写法string str2 = string.Format("my name is {0},my age is {1}.", name, age);//使用$语法糖的写法string str3 = $"my name is {name},my age is {age}.";

public delegate double Calc(double x, double y);class Program{static void Main(string[] args){Calculator calculator = new Calculator();double x = 200;double y = 100;double z;Calc calc1 = new Calc(calculator.Add);Calc calc2 = new Calc(calculator.Sub);Calc calc3 = new Calc(calculator.Mul);Calc calc4 = new Calc(calculator.Div);z = calc1(x, y);Console.WriteLine(z);z = calc2.Invoke(x, y);Console.WriteLine(z);z = calc3.Invoke(x, y);Console.WriteLine(z); z = calc4.Invoke(x, y);Console.WriteLine(z);}}class Calculator{public double Add(double a, double b){return a + b;}public double Sub(double a, double b){return a - b;}public double Mul(double a, double b){return a * b;}public double Div(double a, double b){return a / b;}}

模板方法案例

class Program
{static void Main(string[] args){ProductFactory pf = new ProductFactory();WrapFactory wf = new WrapFactory();Func<Product> func1 = new Func<Product>(pf.MakePizza);Func<Product> func2 = new Func<Product>(pf.MakeToyCar);Box box1 = wf.WrapProduct(func1);Box box2 = wf.WrapProduct(func2);Console.WriteLine(box1.Product.Name);Console.WriteLine(box2.Product.Name);}
}
class Product
{public string Name { get; set; }
}
class Box
{public Product Product { get; set; }
}
class WrapFactory
{public Box WrapProduct(Func<Product> getProduct){Box box = new Box();box.Product = getProduct.Invoke();return box;}
}
class ProductFactory
{public Product MakePizza(){Product product = new Product();product.Name = "Pizza";return product;}public Product MakeToyCar(){Product product = new Product();product.Name = "Toy Car";return product;}
}

回调方法案例

class Program
{static void Main(string[] args){ProductFactory pf = new ProductFactory();WrapFactory wf = new WrapFactory();Func<Product> func1 = new Func<Product>(pf.MakePizza);Func<Product> func2 = new Func<Product>(pf.MakeToyCar);Logger logger = new Logger();Action<Product> action = new Action<Product>(logger.log);Box box1 = wf.WrapProduct(func1, action);Box box2 = wf.WrapProduct(func2, action);Console.WriteLine(box1.Product.Name);Console.WriteLine(box2.Product.Name);}
}
class Logger
{public void log(Product product){Console.WriteLine("Product {0} created at {1}. Price is {2}.", product.Name, DateTime.UtcNow, product.Price); }
}
class Product
{public string Name { get; set; }public int Price { get; set; }
}
class Box
{public Product Product { get; set; }
}
class WrapFactory
{public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback){Box box = new Box();Product product = getProduct.Invoke();if(product.Price>=50){logCallback.Invoke(product);}box.Product = product;return box;}
}
class ProductFactory
{public Product MakePizza(){Product product = new Product();product.Name = "Pizza";product.Price = 12;return product;}public Product MakeToyCar(){Product product = new Product();product.Name = "Toy Car";product.Price = 100;return product;}
}

委托的高级使用

多播委托案例

class Program
{static void Main(string[] args){Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};Student stu2 = new Student() { ID=1, PenColor = ConsoleColor.Green};Student stu3 = new Student() { ID=1, PenColor = ConsoleColor.Red};Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);//单播委托//action1.Invoke();//action2.Invoke();//action3.Invoke();//多播委托action1 += action2;action1 += action3;action1.Invoke();}
}
class Student
{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}
}

隐式异步调用 -- BeginInvoke

class Program
{static void Main(string[] args){Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};Student stu2 = new Student() { ID=2, PenColor = ConsoleColor.Green};Student stu3 = new Student() { ID=3, PenColor = ConsoleColor.Red};Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);//隐式异步调用action1.BeginInvoke(null, null);action2.BeginInvoke(null, null);action3.BeginInvoke(null, null);for (int i = 0; i < 10; i++){Console.ForegroundColor = ConsoleColor.Cyan;Console.WriteLine("Main thread {0}.", i);Thread.Sleep(1000);}}
}
class Student
{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}
}

显式异步调用

注:ctrl+. 给没有定义命名空间的类添加命名空间

class Program{static void Main(string[] args){Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};Student stu2 = new Student() { ID=2, PenColor = ConsoleColor.Green};Student stu3 = new Student() { ID=3, PenColor = ConsoleColor.Red};//显式异步调用Thread thread1 = new Thread(new ThreadStart(stu1.DoHomeWork));Thread thread2 = new Thread(new ThreadStart(stu2.DoHomeWork));Thread thread3 = new Thread(new ThreadStart(stu3.DoHomeWork));thread1.Start();thread2.Start();thread3.Start();//使用task显式异步调用Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);Task task1 = new Task(action1);Task task2 = new Task(action2);Task task3 = new Task(action3);task1.Start();task2.Start();task3.Start();for (int i = 0; i < 10; i++){Console.ForegroundColor = ConsoleColor.Cyan;Console.WriteLine("Main thread {0}.", i);Thread.Sleep(1000);}}}class Student{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}}

可以使用接口来取代委托

以上面的回调方法中的例子作为改进:

class Program
{static void Main(string[] args){IProductFactory pizzaFactory = new PizzaFactory();IProductFactory toycarFactory = new ToycarFactory();WrapFactory wf = new WrapFactory();Box box1 = wf.WrapProduct(pizzaFactory);Box box2 = wf.WrapProduct(toycarFactory);Console.WriteLine(box1.Product.Name);Console.WriteLine(box2.Product.Name);}
}
interface IProductFactory
{Product Make();
}
class PizzaFactory : IProductFactory
{public Product Make(){Product product = new Product();product.Name = "Pizza";product.Price = 12;return product;}
}
class ToycarFactory : IProductFactory
{public Product Make(){Product product = new Product();product.Name = "Toy Car";product.Price = 100;return product;}
}
class Product
{public string Name { get; set; }public int Price { get; set; }
}
class Box
{public Product Product { get; set; }
}
class WrapFactory
{public Box WrapProduct(IProductFactory productFactory){Box box = new Box();Product product = productFactory.Make();box.Product = product;return box;}
}

自己定义委托类型

class Program
{static void Main(string[] args){MyDele dele1 = new MyDele(M1);Student stu = new Student();//dele1 += stu.SayHello;//同上dele1 += (new Studnet()).SayHello;//dele1.Invoke();//同上,与上面相比下面直接调用方法更常用。dele1();}static void M1(){Console.Write("M1 is called");}class Student{public void SayHello(){Concole.WriteLine("Hello, I'm a student!");}}delegate void MyDele();
}

自定义泛型委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DelegateExample
{class Program{static void Main(string[] args){MyDele<int> myDele = new MyDele<int>(Add);int addRed = myDele(2, 4);Console.WriteLine(addRed);MyDele<double> myDele2 = new MyDele<double>(Mul);double mulRed = myDele2(2.2, 2.2);Console.WriteLine(mulRed);//查看委托是否是类Console.WriteLine(myDele.GetType().IsClass);}static int Add(int x, int y){return x + y;}static double Mul(double x, double y){return x * y;}}delegate T MyDele<T>(T a, T b);
}

事件

事件的概念

微软把这种经由事件发送出来的与事件本身相关的数据称为:事件参数

根据通知和事件参数来采取行动的这种行为称为响应事件或处理事件。处理事件时具体所做的事情就叫做事件处理器

事件的应用

案例1.
class Program{static void Main(string[] args){//timer: 事件的拥有者Timer timer = new Timer();timer.Interval = 1000;// boy和girl: 事件的响应者Boy boy = new Boy();//timer.Elapsed: 事件成员; boy.Action: 事件处理器;+=: 事件订阅timer.Elapsed += boy.Action;Girl girl = new Girl();timer.Elapsed += girl.Action;//timer.Enabled = true;timer.Start();Console.ReadLine();}}class Boy{internal void Action(object sender, ElapsedEventArgs e){Console.WriteLine("jump");}}class Girl{internal void Action(object sender, ElapsedEventArgs e){Console.WriteLine("Sing");}}
案例2:图一颗星方式
class Program{static void Main(string[] args){//form: 事件拥有者Form form = new Form();//controller: 事件响应者Controller controller = new Controller(form);form.ShowDialog();}}class Controller{private Form form;public Controller(Form form){this.form = form;//this.form.Click: 事件; +=: 事件订阅this.form.Click += this.FormClicked;}//FormClicked:事件处理器private void FormClicked(object sender, EventArgs e){this.form.Text = DateTime.Now.ToString();}}
案例3:图两颗星方式
class Program{static void Main(string[] args){//form: 事件拥有者和响应者MyForm form = new MyForm();form.Click += form.FormClicked;form.ShowDialog();}}class MyForm : Form{internal void FormClicked(object sender, EventArgs e){this.Text = DateTime.Now.ToString();}}
案例4:图三颗星方式
class Program{static void Main(string[] args){//form: 事件拥有者和响应者MyForm form = new MyForm();        form.ShowDialog();}}this Form: 响应者class MyForm : Form{private TextBox textBox;private Button button;public MyForm(){this.textBox = new TextBox();//this.button: 拥有者this.button = new Button();this.Controls.Add(this.textBox);this.Controls.Add(this.button);this.button.Click += this.ButtonClicked;this.button.Text = "say hello";this.button.Top = 50;}public void ButtonClicked(object sender, EventArgs e){this.textBox.Text = "Hello World!!!!!!!!!!!!!!!!!!";}}
在窗体应用程序中,使用事件的五种方法
namespace EventWindowsForms
{public partial class Form1 : Form{public Form1(){InitializeComponent();//button2. 方法2. 手动订阅this.button2.Click += buttonClick;//button3. 方法3.委托this.button3.Click += new EventHandler(buttonClick);//button4. 方法4. 旧式委托this.button4.Click += delegate (object sender, EventArgs e){this.myTextBox.Text = "button4Clicked!";};//button5. 方法5. lambda表达式this.button5.Click += (sender, e) =>{this.myTextBox.Text = "button5Clicked!";};}//button1. 方法1.直接在设计中双击click自动生成订阅private void buttonClick(object sender, EventArgs e){if(sender==button1){this.myTextBox.Text = "hello!";}if(sender==button2){this.myTextBox.Text = "world!";}if(sender==button3){this.myTextBox.Text = "My.Okey!";}}}
}

事件的定义

事件声明的完整格式

namespace FullFormOfEvent
{class Program{static void Main(string[] args){Customer customer = new Customer();Waiter waiter = new Waiter();customer.Order += waiter.Action;//一定是事件拥有者的内部逻辑触发了该事件customer.Action();customer.PayThisBill();}}public class OrderEventArgs:EventArgs{public string DishName { get; set; }public string Size { get; set; }}//声明委托类型 为声明的order事件用的//当一个委托专门用来声明事件时,名称一般为事件名+EventHandlerpublic delegate void OrderEventHandler(Customer customer, OrderEventArgs e);public class Customer{//声明一个委托类型的字段 引用事件处理器的private OrderEventHandler orderEventHandler;public event OrderEventHandler Order{add{this.orderEventHandler += value;}remove{this.orderEventHandler -= value;}}public double Bill { get; set; }public void PayThisBill(){Console.WriteLine("I will pay ${0}.", this.Bill);}//事件要通过委托来做一个约束,这个委托//既规定了事件发送什么消息给事件的响应者//也规定了事件的响应者能收到什么样的消息//事件响应者的事件处理器必须能够跟约束匹配上,才能订阅事件//当事件的响应者向事件的拥有者提供了能够匹配这个事件的事件处理器之后,//需要将此处理器保存或记录下来,能够记录或引用方法的任务只有//引用委托的实例才能够做到。//事件这种成员,无论从表层约束上来讲,还是从底层实现来讲,都依赖委托类型public void WalkIn(){Console.WriteLine("Walk into the restaurant.");}public void SitDown(){Console.WriteLine("Sit down.");}public void Think(){for (int i = 0; i < 5; i++){Console.WriteLine("Let me think。。。");Thread.Sleep(1000);}if(this.orderEventHandler!=null){OrderEventArgs e = new OrderEventArgs();e.DishName = "Kongpao Chicken";e.Size = "large";this.orderEventHandler.Invoke(this, e);}}public void Action(){Console.ReadLine();this.WalkIn();this.SitDown();this.Think();}}public class Waiter{internal void Action(Customer customer, OrderEventArgs e){Console.WriteLine("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;}customer.Bill += price;}}
}

事件声明的简略格式

只修改了两个部分

namespace FullFormOfEvent
{class Program{static void Main(string[] args){Customer customer = new Customer();Waiter waiter = new Waiter();customer.Order += waiter.Action;//一定是事件拥有者的内部逻辑触发了该事件customer.Action();customer.PayThisBill();}}public class OrderEventArgs:EventArgs{public string DishName { get; set; }public string Size { get; set; }}//声明委托类型 为声明的order事件用的//当一个委托专门用来声明事件时,名称一般为事件名+EventHandlerpublic delegate void OrderEventHandler(Customer customer, OrderEventArgs e);public class Customer{
// 修改1public event OrderEventHandler Order;public double Bill { get; set; }public void PayThisBill(){Console.WriteLine("I will pay ${0}.", this.Bill);}public void WalkIn(){Console.WriteLine("Walk into the restaurant.");}public void SitDown(){Console.WriteLine("Sit down.");}public void Think(){for (int i = 0; i < 5; i++){Console.WriteLine("Let me think。。。");Thread.Sleep(1000);}
//修改2//和详细声明相比,现在用了一个事件的名字取代了过去这个字段上的名字//之前的委托类型字段还在,只不过没有出现在代码中if(this.Order!=null){OrderEventArgs e = new OrderEventArgs();e.DishName = "Kongpao Chicken";e.Size = "large";this.Order.Invoke(this, e);}}public void Action(){Console.ReadLine();this.WalkIn();this.SitDown();this.Think();}}public class Waiter{internal void Action(Customer customer, OrderEventArgs e){Console.WriteLine("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;}customer.Bill += price;}}
}

省去了委托类型的声明,而是使用了通用的EventHandler

namespace FullFormOfEvent
{class Program{static void Main(string[] args){Customer customer = new Customer();Waiter waiter = new Waiter();customer.Order += waiter.Action;//一定是事件拥有者的内部逻辑触发了该事件customer.Action();customer.PayThisBill();}}public class OrderEventArgs:EventArgs{public string DishName { get; set; }public string Size { get; set; }}public class Customer{//省去了委托类型的声明,而是使用了通用的EventHandlerpublic event EventHandler Order;public double Bill { get; set; }public void PayThisBill(){Console.WriteLine("I will pay ${0}.", this.Bill);}public void WalkIn(){Console.WriteLine("Walk into the restaurant.");}public void SitDown(){Console.WriteLine("Sit down.");}public void Think(){for (int i = 0; i < 5; i++){Console.WriteLine("Let me think。。。");Thread.Sleep(1000);}//和详细声明相比,现在用了一个事件的名字取代了过去这个字段上的名字//之前的委托类型字段还在,只不过没有出现在代码中if(this.Order!=null){OrderEventArgs e = new OrderEventArgs();e.DishName = "Kongpao Chicken";e.Size = "large";this.Order.Invoke(this, e);}}public void Action(){Console.ReadLine();this.WalkIn();this.SitDown();this.Think();}}public class Waiter{internal void Action(Object sender, EventArgs e){Customer customer = sender as Customer;OrderEventArgs orderInfo = e as OrderEventArgs;Console.WriteLine("I will serve you the dish - {0}.", orderInfo.DishName);double price = 10;switch (orderInfo.Size){case "small":price = price * 0.5;break;case "large":price = price * 1.5;break;default:break;}customer.Bill += price;}}
}

事件与委托的关系

lambda表达式

是匿名和inline方法

//lambda表达式:方法1
Func<int, int, int> func = new Func<int, int, int>((int a, int b)=> { return a + b; });
int res = func(3, 5);
Console.WriteLine($"a+b={res}");
//方法2
func = new Func<int, int, int>((x, y) => { return x * y; });
res = func(3, 5);
Console.WriteLine($"a*b={res}");
//方法3 最常用
func = (x, y) => { return x - y; };
res = func(3, 5);
Console.WriteLine($"a-b={res}");

使用函数来调用lambda表达式(泛型委托的类型参数推断)

DoSomeCalc((a, b)=> { return a + b; }, 100, 200);
static void DoSomeCalc<T>(Func<T, T, T>func, T x, T y)
{T res = func(x, y);Console.WriteLine(res);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146193.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

全国排名前三的直播公司无锋科技入驻天府蜂巢成都直播产业基地

最近&#xff0c;全国排名前三的直播公司——无锋科技&#xff0c;正式宣布入驻位于成都的天府蜂巢直播产业基地&#xff0c;这一消息引起了业内人士的高度关注。成都直播产业基地一直是中国直播产业的重要地标之一&#xff0c;其强大的技术和资源优势为众多直播公司提供了广阔…

26 docker前后端部署

[参考博客]((257条消息) DockerNginx部署前后端分离项目(SpringBootVue)的详细教程_在docker中安装nginx实现前后端分离_这里是杨杨吖的博客-CSDN博客) (DockerNginx部署前后端分离项目(SpringBootVue)) 安装docker # 1、yum 包更新到最新 yum update # 2、安装需要的软件包…

csgo盲盒支付接口如何申请?

csgo盲盒支付接口如何申请&#xff1f;个人认为没什么特别难懂的&#xff01; 第一点&#xff1a;确定网站的基本功能&#xff01;每个网站的玩法大概都是一样的&#xff0c;无非是拆箱盲盒&#xff0c;ROLL房间、决斗、货物、生存和更换合同&#xff0c;然后有积分购物中心&am…

vue 实现数字验证码功能

需求&#xff1a;写了一个 手机发送验证码后 输入固定验证码的功能 封装成一个组件,如下: <template><div class"conts"><div class"box"><div class"code_list"><div :class"[ code_item, hideIndex 0 ? co…

Flutter笔记:滚动之-无限滚动与动态加载的实现

Flutter笔记 无限滚动与动态加载的实现 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133342307 本文还…

分享10个必备的VS Code技巧和窍门,提高你的开发效率

目录 前言 1. 时间线视图&#xff1a;本地源代码控制 2. 自动保存&#xff1a;不再需要按Ctrl S 3. 使用命令面板进行任何操作 4、快速转到文件 5. 快速跳转指定行 6. 快速删除该行 7. 享受使用流畅的光标进行打字 8. 快速格式化代码 9. 使用多光标编辑功能节省时间…

【智能家居项目】裸机版本——项目介绍 | 输入子系统(按键) | 单元测试

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;项目简介&#x1f3c0;输入子系统(按键)⚽应用层⚽设备层⚽ 内核层抽象层⚽…

flink选择slot

flink选择slot 在这个类里修改 package org.apache.flink.runtime.resourcemanager.slotmanager.SlotManagerImpl; findMatchingSlot(resourceProfile)&#xff1a;找到满足要求的slot&#xff08;负责从哪个taskmanager中获取slot&#xff09;对应上图第8&#xff0c;9&…

IDEA 使用

目录 Git.gitignore 不上传取消idea自动 add file to git撤销commit的内容本地已经有一个开发完成的项目&#xff0c;这个时候想要上传到仓库中 Git .gitignore 不上传 在项目根目录下创建 .gitignore 文件夹&#xff0c;并添加内容&#xff1a; .gitignore取消idea自动 add…

【OpenCV-Torch-dlib-ubuntu】Vm虚拟机linux环境摄像头调用方法与dilb模型探究

前言 随着金秋时节的来临&#xff0c;国庆和中秋的双重喜庆汇聚成一片温暖的节日氛围。在这个美好的时刻&#xff0c;我们有幸共同迎来一次长达8天的假期&#xff0c;为心灵充电&#xff0c;为身体放松&#xff0c;为未来充实自己。今年的国庆不仅仅是家国团聚的时刻&#xff…

STL容器

C STL STL实现原理及其实现 STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;&#xff0c;提供了六大组件&#xff0c;可以相互之间组合套用&#xff0c;这六大组件分别是&#xff1a;容器&#xff08;Containers&#xff09;&#xff0c;算法&a…

1.6.C++项目:仿muduo库实现并发服务器之channel模块的设计

项目完整版在&#xff1a; 文章目录 一、channel模块&#xff1a;事件管理Channel类实现二、提供的功能三、实现思想&#xff08;一&#xff09;功能&#xff08;二&#xff09;意义&#xff08;三&#xff09;功能设计 四、代码&#xff08;一&#xff09;框架&#xff08;二…

凉鞋的 Godot 笔记 103. 检视器 :节点的微观编辑和查看

在上一篇&#xff0c;笔者简单介绍了场景与节点的增删改查&#xff0c;如下所示: 在这一篇&#xff0c;我们接着往下学习。 我们知道在场景窗口&#xff0c;可以对节点进行增删改查。 在 Godot 引擎使用过程中&#xff0c;场景窗口的使用频率是非常高的。 但是场景窗口只能编…

macOS Sonoma 14 正式版(23A344)发布,附黑/白苹果镜像下载地址

系统介绍&#xff08;系统下载地址&#xff1a;http://www.imacosx.cn/115300.html&#xff09; 黑果魏叔9 月 27日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS Sonoma 14 正式版&#xff08;23A344&#xff09;。 macOS 14正式版系统发布&#xff1a;全新功能与改…

ChatGPT Prompting开发实战(十二)

一、如何开发prompts实现个性化的对话方式 通过设置“system”和“user”等roles&#xff0c;可以实现个性化的对话方式&#xff0c;并且可以结合参数“temperature”的设定来差异化LLM的输出内容。在此基础上&#xff0c;通过构建一个餐馆订餐对话机器人来具体演示对话过程。…

Arcgis克里金插值报错:ERROR 010079: 无法估算半变异函数。 执行(Kriging)失败。

Arcgis克里金插值报错&#xff1a;ERROR 010079: 无法估算半变异函数。 执行(Kriging)失败。 问题描述&#xff1a; 原因&#xff1a; shape文件的问题&#xff0c;此图可以看出&#xff0c;待插值的点有好几个都超出了地理范围之外&#xff0c;这个不知道是坐标系配准的问…

JAVA设计模式-代理模式

一.概念 在软件开发中&#xff0c;也有一种设计模式可以提供与代购网站类似的功能。由于某些原因&#xff0c;客户端不想或不能直接访问一个对象&#xff0c;此时可以通过一个称之为“代理”的第三者来实现间接访问&#xff0c;该方案对应的设计模式被称为代理模式。 ​ 代理模…

数据结构——堆(C语言)

本篇会解决一下几个问题&#xff1a; 1.堆是什么&#xff1f; 2.如何形成一个堆&#xff1f; 3.堆的应用场景 堆是什么&#xff1f; 堆总是一颗完全二叉树堆的某个节点总是不大于或不小于父亲节点 如图&#xff0c;在小堆中&#xff0c;父亲节点总是小于孩子节点的。 如图&a…

GO 比较两个对象是否相同

本文主要是来聊一聊关于 Golang 中的深度比较 DeepEqual 因为最近发现身边的小伙伴写 2 个或者多个 map 比较的时候&#xff0c;都是自己去实现去比较每一个结构&#xff0c;每一个节点的 key 和 value 是不是都相等&#xff0c;且根据不同的数据结构&#xff0c;都要去实现一…

【Python】基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作

【Python】基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 文章目录 手势识别人脸追踪键盘控制整体代码附录&#xff1a;列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 视频&#xff1a; 基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 手…