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#------委托与事件(一篇文章彻底搞懂...)
一:委托 所有的代码语言创造者母语都是英语,我们从英语翻译到中文的过程中难免会存在一些不太能还原本意的词,比如我之前一直不理解构造函数和析构函数,只知道这俩货作用相反,直到我看到了它的英文意思,Con…...
别再为 Jenkins 安装烦恼,Docker 帮你轻松解决
前言 大家好,又见面了,我是沐风晓月,本文收录与云原生相关的专栏,以下是我的简介: 🏠个人主页:我是沐风晓月 🧑个人简介:大家好,我是沐风晓月,双…...
汇编语言程序设计(一)
前言 在学习汇编语言之前,我们应该要知道汇编语言他是一门怎么样的语言。汇编语言是直接工作在硬件上的一门编程语言,学习汇编语言之前最好先了解一下计算机硬件系统的结构和工作原理。学习汇编语言的重点是学习如何利用硬件系统的编程结构和指令集进而…...
【uni-app教程】四、UniAPP 路由配置及页面跳转
四、UniAPP 路由配置及页面跳转 (1) 路由配置 uni-app页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue …...
ROS从入门到精通系列(二十八)-- ROS控制器图形化界面开发
ROS (Robot Operating System, 机器人操作系统) 作为机器人软件中的通信及控制中间件,提供一系列程序库和工具以帮助软件开发者创建机器人应用软件。它提供了硬件抽象、设备驱动、函数库、可视化工具、消息传递和软件包管理等诸多功能。ROS遵循BSD开源许可协议。 随着机器人智…...
Submodule命令:android如何将自己项目中的某个Module作为gitlab中第三方公共库
一、创建远程公共库 1、Android Studio创建本地仓库 创建一个新的module 在新建module中添加代码(此处示例代码) 右击新建的module,打开新建module的命令行界面, 因为我们只上传这个module的代码,而不是整个项目的代码 命令行中输入以下命令…...
MySQL索引事务
1.索引1.1概念索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结果实现。(这里只用通俗的语言和图片进行介绍)1.2作用数据库中的表…...
ISO27001信息安全管理体系认证
ISO信息安全管理体系认证 一、什么是ISO信息安全管理体系认证? ISO是信息安全管理体系认证,是由国际标准化组织(ISO)采纳英国标准协会BS-2标准后实施的管理体系,成为了“信息安全管理”的国际通用语言,企…...
Linux应用GUI开发C++ 之gtkmm4(1)
目录概述GTKgtkmm安装gtkmm4hello,worldcodelite配置代码解释概述 GTK GTK是一个小部件工具包。GTK创建的每个用户界面都由小部件组成。这是在C语言中使用GObject实现的,GObject是一个面向对象的C语言框架。窗口小部件是主容器。然后通过向窗口中添加按钮、下拉菜…...
选课系统的设计与实现
技术:Java等摘要:目前国内各高校的规模越来越大,进而造成教师教学管理等工作量日趋加大。然而,现代教育的信息化、网络化已经成为教育发展的一个重要方向,同时也为解决高校教学管理效率低下的现状,使管理突…...
关于安卓的一些残缺笔记
安卓笔记Android应用项目的开发过程Android的调试Android项目文档结构Intent的显式/隐式调用Activity的生命周期1个Activity界面涉及到生命周期的情况2个Activity界面涉及到生命周期的情况Android布局的理论讲解Activity界面布局ContentProvider是如何实现数据共享Android整体架…...
MySQL 中的锁有哪些类型,MySQL 中加锁的原则
锁的类型MySQL 找那个根据加锁的范围,大致可以分成全局锁,表级锁和行级锁。全局锁全局锁,就是对整个数据库加锁。加锁flush tables with read lock解锁unlock tables全局锁会让整个库处于只读状态,之后所有的更新操作都会被阻塞&a…...
Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作
场景 Sqlite数据库 SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。 就像其他数据库,SQLite 引擎不…...
2023最新版本RabbitMQ下载安装教程
一、RabbitMQ简介 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。主要用于在进程、应用程序和服务器之间交换数据,可以通过插件支持进行扩展,支持许多协议,并提供高性能、可靠性、集群和高可用队列。 AMQP :Advanced Me…...
如何使用码匠连接 Elasticsearch
目录 在码匠中集成 Elasticsearch 在码匠中使用 Elasticsearch 关于码匠 Elasticsearch 是一个开源的分布式搜索和分析引擎,常用于处理大规模数据集的搜索、实时数据分析和数据挖掘任务。它支持多种数据源,包括关系型数据库(如 MySQL、Pos…...
jmeter学习笔记二(jmeter函数与后置处理器)
Jmeter重要的函数 ${__counter(,)} 计数器 ${__counter(TRUE,)} 默认加1; TRUE,每个用户有自己的计数器;FALSE,使用全局计数器 计数器元件,可以设置起始值,间隔值,最大值。运行结果超过最大值时&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的作用: 不是程序本身,可以对程序做出解释(这一点和注释comment没什么区别)可以被其他程序ÿ…...
【C++】string
【C修炼秘籍】string 目录 【C修炼秘籍】string 文章目录 前言 一、标准库里的string 二、string常用接口功能简介(具体使用和底层转到模拟实现) 1、string类的常见构造函数 2、string类对象的容量操作 3、string类对象的访问及遍历操作 4、 string类对象…...
JVM详解——执行引擎
如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:耶瞳空间 一:执行引擎介绍 “虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和…...
python学习——【第二弹】
前言 上一篇文章 python学习——【第一弹】给大家介绍了python中的基本数据类型等,这篇文章接着学习python中的运算符的相关内容。 运算符 python中的运算符主要有:算术运算符,赋值运算符,比较运算符,布尔运算符以及…...
242. 有效的字母异位词 349. 两个数组的交集
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意: 若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat…...
web网页设计——JavaScript一些语法
1、事件监听 语法: <1> 元素对象.addEventListener(‘事件类型’,要执行的函数) 三要素:(1)、事件源 (2)事件类型 (3)执行的函数 <2>元素对象.on事件类型 …...
php宝塔搭建部署实战CSM会议室预约系统源码
大家好啊,我是测评君,欢迎来到web测评。 本期给大家带来一套基于fastadmin开发的CSM会议室预约系统的源码。感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码࿰…...
嵌入式知识点-SPI通讯
该文原自 : 正点原子 01 SPI概述 SPI (Serial Peripheralinterface),顾名思义就是串行外围设备接口。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同…...
C#教程--01 简介
简介 C# 是一个简单的、现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的。 C#的特性 现代的、通用的编程语言。 面向对象。 面向组件。 容易学习。 结构化语言。 它产生高效率的程序。 它可以在多种计算机平台上编译。 .Net 框架的一部分。 C#强大的编程…...
【java基础】一篇文章彻底搞懂lambda表达式
文章目录lambda表达式是什么lambda表达式的语法函数式接口初次使用深入理解方法引用 :: 用法快速入门不同形式的::情况1 object::instanceMethod情况2 Class::instanceMethod情况3 Class::staticMethod对于 :: 的一些示例及其注意事项构造器引用变量作用域使用外部变量定义内部…...
通用SQL查询分析器
技术:Java、JSP等摘要:本文主要针对当前很多软件都无法实现跨数据库、跨平台来执行sql语句而用户又仅需做一些基本的增删改查操作的矛盾,设计了一个能够跨平台跨数据库的软件。此软件是一个通用SQL查询分析器,利用java语言本身的跨…...
机器学习100天(三十八):038 朴素贝斯-处理离散数据
《机器学习100天》完整目录:目录 机器学习100天,今天讲的是:朴素贝斯-处理离散数据! 打开 spyder,新建一个 naive_bayes_category.py 脚本。上一节我们引入了一批西瓜样本。并使用朴素贝叶斯公式计算出一个瓜蒂脱落、圆形、青色的西瓜是熟瓜的概率。下面我们来使用 pytho…...
【3.3】指针、二分、SSM项目
二分查找 class Solution {public int search(int[] nums, int target) {int n nums.length;int left 0;int right n - 1;while(left < right){int mid left (right - left) / 2;if(nums[mid] < target){left mid 1;}else if(nums[mid] > target){right mid …...
建立网站不公开/免费个人网站源码
设计模式6大原则-单一职责原则 定义:一个类应该只有一个引起变化的原因。一个类只负责一项职责 如果一个类有多个职责,这些职责耦合在一起,当一个职责发生变化时,可能影响其他的职责。 如: 一个类有 A、B、C 等职责…...
金泉网网站建设/网站优化入门
dva的思想还是很不错的,大大提升了开发效率,dva集成了Redux以及Redux的中间件Redux-saga,以及React-router等等。得益于Redux的状态管理,以及Redux-saga中通过Task和Effect来处理异步的概念,dva在这些工具的基础上高度封装,只暴露…...
网站建设 推广/搜索词分析
深深以为,遇见一个好的文章不容易,希望自己也能用心填坑。 首先来说读取用户信息,之前是用getUserInfo(),但在2018年4月30日之后,该接口不适用于开发版和测试版,正式上线的小程序不受影响。很不幸ÿ…...
可以做动画的网站都有哪些软件/网络营销招聘
在服务器端程序开发领域,性能问题一直是备受关注的重点。业界有大量的框架、组件、类库都是以性能为卖点而广为人知。然而,服务器端程序在性能问题上应该有何种基本思路,这个却很少被这些项目的文档提及。本文正式希望介绍服务器端解决性能问…...
wordpress基础模板/如何制作一个网址
图数据库作为新兴NoSQL数据库的代表,可以分为四种类型。图数据库应用广泛,无论是互联网行业还是传统的金融、地产、医疗等行业,都可以通过图数据库的应用进一步提升企业效率。数易轩致力于图数据库技术服务,为您介绍图数据库的四个…...
wordpress插件 数据列表/百度文库官网登录入口
使用目录查看更佳! Redis学习 Redis Redis中文网教程:https://www.redis.net.cn/tutorial/3501.html 概念 redis是一款高性能的NOSQL系列的非关系型数据库 什么是NOSQL? NoSQL(NoSQL Not Only SQL),意即“不仅仅是SQL”&a…...