万字长文说说C#和Rust_Cangjie们的模式匹配

C#11新增列表模式后,这个从C#6就开始的特性,算是拼接好了模式匹配的最后一块拼图。对比Swift、Rust或Cangjie这类先天支持模式匹配的语言,能否一战?今天就来全面battle一下。Swift、Rust和Cangjie的模式匹配,一肪相承,这次对比,赶个热度,选取Cangjie。(Swift不熟悉,略懂Rust,据说Rust的模式匹配是抄Swift的?)

一、先说结论

  1. 模式匹配用于判断表达式是否符合某种特征,相对于普通的常量比较,它的比较范围更加丰富,比如可以比较类型。C#中,模式匹配可以用于switch表达式、switch语句、is表达式(常用于if语句);Cangjie中,模式匹配可用于match表达式、if-let表达式和if-while表达式。
  2. C#的模式匹配已经相当完整,覆盖了类型(类型模式)、基本类型(常量模式)、对象类型(属性模式)、元组类型(位置模式)、列表类型(列表模式),同时实现了通配符(弃元)、pattern guard(when)、表达式的捕获(var匹配任意表达式)、关系和逻辑运算等。打补丁走到强过天生模式匹配,相当哇塞、相当逆天了!!!
  3. Cangjie的模式匹配,目前应该还算是一个半成品,比如以下功能“似乎”还没有实现:对象类型匹配、列表类型匹配、关系和复杂逻辑运算等。

二、前置知识点

1.1 C#的switch表达式和is表达式

大多数情况下,我们都是使用switch和if语句,比较少接触switch和is表达式,尤其是switch表达式,好些人可能从来都没用过。

1.1.1 switch表达式
//使用方式1:函数式=============================================================
class Program
{static void Main(string[] args){var score = 100;Console.WriteLine(ReadScore(score));}//使用了常量匹配、逻辑匹配和关系匹配//【=> 参数 switch】,将参数带入方法体static string ReadScore(int num) => num switch{100 => "满分", //每个匹配逗号分隔>=80 and <100 => "A",>=60 and <80 => "B",>=0 and <60 => "不及格",_ => $"无效分{num}"  //读取参数值}; //分号结尾
}//使用方式2:表达式=============================================================
class Program
{static void Main(string[] args){var score = 100;var result = score switch{100 => "满分",>= 80 and < 100 => "A",>= 60 and < 80 => "B",>= 0 and < 60 => "不及格",_ => $"无效分{score}"}; //分号结尾Console.WriteLine(result);}
}
1.1.2 is表达式
//1、在if语句中使用==============================================================
//判断是否为null,常量模式匹配-----------
if (input is null)
{return;
}//判断是否不为null------------------------------
if (result is not null)
{Console.WriteLine(result.ToString());
}//类型/声明模式匹配----------------------------
int i = 34;
object iBoxed = i;
int? jNullable = 42;
//iBoxed表达式的值是否属于int类型,如果是,则将值赋值给变量a
//jNullable表达式的值是否属于int类型,如果是,则将值赋值给变量b
//注意并集条件用&&
if (iBoxed is int a && jNullable is int b)
{Console.WriteLine(a + b);  // 76
}//和switch一样,也可以在方法中使用---------------
//如下is返回一个布尔值。而switch是分支选择。
//以下使用到了属性匹配,详见本文的模式匹配
static bool IsFirstFridayOfOctober(DateTime date) => date is { Month: 10, Day: <=7, DayOfWeek: DayOfWeek.Friday };

1.2 Cangjie的枚举类型

Cangjie们的枚举类型是代数数据类型,枚举值可以带参。框架内置了一个非常重要的泛型枚举Option,用于实现可空(第一次在Rust中看见这种可空实现,还是很震惊的)。可空变量的值,无论是空值还是有值,都被Option类型的枚举值包裹,需要通过模式匹配取出,所以枚举类型和模式匹配的关联性很强。当然,匹配枚举类型只是模式匹配的应用之一。
对于Cangjie的枚举,多说两句。它和Rust一样,是代数数据类型,但又阉割了一些功能,比如命名属性。和Rust一样,使用Option实现了可空类型,但异常又不像Rust一样使用Result<T, E>,而是使用传统的throw和try…catch…finally。无法评价优劣,但撕裂感是比较强烈的。

1.2.1 枚举和内置枚举类型Option
//1、枚举=======================================================================
//Cangjie中枚举选项称为构造器
//构造器可以带参数,而且类似方法,可以重载
//在枚举中,还可以定义成员函数、操作符函数和成员属性,本例略
enum RGBColor {| Red | Green | Blue| Red(UInt8) | Green(UInt8) | Blue(UInt8)
}
//使用枚举
main() {let r = RGBColor.Red //通过【类型名.构造器】创建枚举实例let g = Green //如果没有Green命名冲突,可以直接使用构造器创建枚举实例let b = Blue(100) //带参数的枚举实例,Blue(100)和Blut(101),是不同的值
}//2、Option<T>枚举==============================================================
//Option<T>枚举由框架提供,通过Option<T>实现框架的可空
//定义如下:
enum Option<T> {| Some(T) //有值构造器,其中T为值的类型| None //空值构造器
}
//使用Option<T>枚举
let a: Option<Int64> = Some(100) //Option<Int64>类型,Some(..)直接使用构造器创建实例
let b: ?Int64 = Some(100) //【?Int64】是Option<Int64>的简写,这就接近C#的可空表达了
let c: Option<String> = Some("Hello")
let d: ?String = Nonelet b: ?Int64 = 100 //这个写法不会报错,编译器会使用Some包装。所以b==100,结果是false
let a = None<Int64> //等价于let a: ?Int64=None。如果let a=None,报错,因为无法确定类型
1.2.2 通过match模式匹配获取Option的T值
//1、通过模式匹配获取T值========================================================
func getString(p: ?Int64): String{match (p) {case Some(x) => "${x}" //使用到了绑定匹配,取出x值case None => "none"}
}
main() {let a = Some(1)let b: ?Int64 = Nonelet r1 = getString(a)let r2 = getString(b)println(r1)println(r2)
}//2、当然,Cangjie也提供了解构T值的语法糖-getOrThrow方法
main() {let a = Some(1)let b: ?Int64 = Nonelet r1 = a.getOrThrow()println(r1)try {let r2 = b.getOrThrow()} catch (e: NoneValueException) {println("b is None")}
}
1.2.2 if-let和if-while(类似C#中的is)
//macth用于分支选择,if-let用于真假判断,也可用于提升Some(T)的T值
main() {let result = Option<Int64>.Some(2023)if (let Some(value) <- result) {println("操作成功,返回值为:${value}")} else {println("操作失败")}
}//whilt-let和if-let差不多,只是while通过条件判断来循环执行语句
func recv(): Option<UInt8> {let number = Random().nextUInt8()if (number < 128) {return Some(number)}return None
}main() {//判断循环while (let Some(data) <- recv()) {println(data)}println("receive failed")
}

三、C#的模式匹配

2.1 类型模式

//1、匹配类型===================================================================
/*验证表达式的运行时类型是否与给定类型兼容,兼容有三种情况1)表达式类型是给定类型是的子类2)表达式类型是给定类型是的实现类3)或者存在从给定类型到表达式类型的隐式转化(如装箱拆箱)
*///下例中,object和string存在隐式转化------------------------
object greeting = "Hello, World!";
if (greeting is string message) //如果匹配,表达式结果将赋值给尾随局部变量message
{Console.WriteLine(message.ToLower());  // output: hello, world!
}//下例中,表达式类型分别是给定类型的子类或实现类-------------
//switch表达式用于分支选择,必须穷尽所有情况,最后一个分支通常使用_,类似default
var numbers = new int[] { 10, 20, 30 };
Console.WriteLine(GetSourceLabel(numbers));  // 1var letters = new List<char> { 'a', 'b', 'c', 'd' };
Console.WriteLine(GetSourceLabel(letters));  // 2static int GetSourceLabel<T>(IEnumerable<T> source) => source switch
{//array和collection类似is表达式中的尾随局部变量Array array => 1, //int[]是Array的子类ICollection<T> collection => 2, //List<char>是ICollection<T>的实现类_ => 3, //通配符,匹配任何表达式
};//2、弃元_,用于匹配任何表达式====================================================
//弃元除了用于switch的分支,还可以用于类型模式、位置模式和列表模式,类似占位符
//下例中,弃元用于匹配类型模式中的局部变量,以及通配符
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{Car _ => 2.00m,null => throw new ArgumentNullException(nameof(vehicle)),_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};

2.2 常量模式

//匹配常量
/*验证表达式的值是否与给定常量匹配(包括相等、比较、逻辑等),适用于以下类型或值1)数值、布尔、字符、字符串2)enum值、const字段3)null(见1.1.2节)
*///1、常量相等匹配===============================================================
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{1 => 12.0m,2 => 20.0m,3 => 27.0m,4 => 32.0m,0 => 0.0m,_ => throw new ArgumentException($"不支持: {visitorCount}", nameof(visitorCount)),
};//2、常量比较匹配===============================================================
//<、>、<= 或 >= 中的任何一个
static string Classify(double measurement) => measurement switch
{< -4.0 => "Too low",> 10.0 => "Too high",double.NaN => "Unknown",_ => "Acceptable",
};//3、逻辑匹配====================================================================
//使用and or not (),匹配多种模式,除了用于常量匹配,也可用于其它匹配模式
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 3, 14)));  // 春
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 7, 19)));  // 夏
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 2, 17)));  // 冬static string GetCalendarSeason(DateTime date) => date.Month switch
{>= 3 and < 6 => "春",>= 6 and < 9 => "夏",>= 9 and < 12 => "秋",12 or (>= 1 and < 3) => "冬",_ => throw new ArgumentException(nameof(date), $"找不到{date.Month}."),
};

2.3 属性模式

//1、属性模式的基本使用=========================================================
//如果表达式的值是复杂类型,如类、结构体,可以匹配表达式结果(对象实例)的属性值
//属性值可以当成常量,使用相等、比较、逻辑等方式匹配
//如下例中date是DateTime的实例,匹配属性Year为2020,Month为5...
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };//2、属性模式和类型模式一起使用==================================================
Console.WriteLine(TakeFive("Hello, world!"));  //  Hello
Console.WriteLine(TakeFive("Hi!"));  //  Hi!
Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6'}));  // 12345
Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' }));  // abcstatic string TakeFive(object input) => input switch
{//匹配类型stringstring s => s,//匹配类型string,且Length属性即字符长度>=5string { Length: >= 5 } s => s.Substring(0, 5),//匹配类型ICollection<char>(表达式值是其实现类)ICollection<char> symbols => new string(symbols.ToArray()),//匹配类型ICollection<char>,且Count属笥即元素个数>=5ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),//其它匹配情况null => throw new ArgumentNullException(nameof(input)),_ => throw new ArgumentException("Not supported input type."),
};//3、属性模式的嵌套=============================================================
public record Point(int X, int Y);
public record Segment(Point Start, Point End);
//嵌套属性
static bool IsAnyEndOnXAxis(Segment segment) =>segment is { Start: { Y: 0 } } or { End: { Y: 0 } };
//重构一下
static bool IsAnyEndOnXAxis(Segment segment) =>segment is { Start.Y: 0 } or { End.Y: 0 };

2.4 位置模式

//1、解构器======================================================================
//1.1 什么是解构器-----------------------------------
//C# 中的 Deconstruct 方法(解构器)可以让实例能像元组一样被析构
//它是一种公开无返回值的方法,方法名必须为Deconstruct,且所有参数均为out参数
public class Point
{public int X { get; }public int Y { get; }public Point(int x, int y){ X = x; Y = y; }//解构器,public void Deconstruct(out int x, out int y){x = X;y = Y;}
}
//使用解构器分解 Point 对象的成员
Point point = new Point(10, 20);
var (x, y) = point; 
Console.WriteLine($"x: {x}, y: {y}"); //1.2 按位置匹配含有Deconstruct解构器的对象------------
static string Classify(Point point) => point switch
{(0, 0) => "Origin",(1, 0) => "positive X basis end",(0, 1) => "positive Y basis end",_ => "Just a point",
};//2、多参数,也可以使用元组对参数进行包装,然后使用位置匹配=======================
//每个位置,都可以使用常量相等、比较、逻辑、弃元、类型、属性等匹配模式
static decimal GetGroupTicketPriceDiscount(int groupSize, DateTime visitDate)=> (groupSize, visitDate.DayOfWeek) switch
{(<= 0, _) => throw new ArgumentException("Group size must be positive."),(_, DayOfWeek.Saturday or DayOfWeek.Sunday) => 0.0m,(>= 5 and < 10, DayOfWeek.Monday) => 20.0m,(>= 10, DayOfWeek.Monday) => 30.0m,(>= 5 and < 10, _) => 12.0m,(>= 10, _) => 15.0m,_ => 0.0m,
};//3、可以使用命名元组元素的名称,或者Deconstruct解构器的参数名称==================
//var用于捕获位置元素,并赋值给局部变量sum
var numbers = new List<int> { 1, 2, 3 };
if (SumAndCount(numbers) is (Sum: var sum, Count: > 0))
{Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}"); 
}
//根据给定整数列表,生成由(求合,求数)组成的命名元组
static (double Sum, int Count) SumAndCount(IEnumerable<int> numbers)
{int sum = 0;int count = 0;foreach (int number in numbers){sum += number;count++;}return (sum, count);
}

2.5 列表模式

//1、列表模式和位置模式比较像,位置模式用于元组,列表模式用于数组或列表=============
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]);  // True
Console.WriteLine(numbers is [1, 2, 4]);  // False
Console.WriteLine(numbers is [1, 2, 3, 4]);  // False
Console.WriteLine(numbers is [0 or 1, <= 2, >= 3]);  // True//2、弃元_可以匹配任何表达式,var用于捕获位置元素,并赋值给局部变量================
List<int> numbers = new() { 1, 2, 3 };
if (numbers is [var first, _, _])
{Console.WriteLine($"The first element of a three-item list is {first}.");
}//3、切片模式,[..]最多只能使用一次==============================================
Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]);  // True
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]);  // True
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]);  // False
Console.WriteLine(new[] { 1 } is [1, 2, ..]);  // FalseConsole.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]);  // True
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]);  // False
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]);  // TrueConsole.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]);  // True
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]);  // True
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]);  // False//4、列表模式其它模式一起使用===================================================
var result = numbers is [< 0, .. { Length: 2 or 4 }, > 0] ? "valid" : "not valid";
var result = message is ['a' or 'A', .. var s, 'a' or 'A']? $"Message {message} matches; inner part is {s}.": $"Message {message} doesn't match.";

2.6 var和when

//var用于匹配任何表达式(包括 null),并将其结果分配给新的局部变量(捕获)
//when用于对表达式进行进一步判断匹配
public record Point(int X, int Y);static Point Transform(Point point) => point switch
{var (x, y) when x < y => new Point(-x, y),var (x, y) when x > y => new Point(x, -y),var (x, y) => new Point(x, y),
};static void TestTransform()
{Console.WriteLine(Transform(new Point(1, 2)));  // Point { X = -1, Y = 2 }Console.WriteLine(Transform(new Point(5, 2)));  // Point { X = 5, Y = -2 }
}

四、Cangjie的模式匹配

3.1 类型模式(C#的类型模式)

//父类
open class Base {var a: Int64public init() {a = 10}
}
//子类
class Derived <: Base {public init() {a = 20}
}
//匹配类型
main() {var d = Derived()var r = match (d) {case b: Base => b.a //匹配上,b可以是任意标识符,类似C#的尾随变量case _ => 0}
}
//如果不需要捕获变量,可以使用通配符
main() {var d = Derived()var r = match (d) {case _: Base => 1 //匹配上case _ => 0}
}

3.2 常量模式(C#的常量模式)

//不能使用关系运算和复杂的逻辑运算
//Rust中可以使用区间0..10,但Cangjie目前还不支持
main() {let score = 90let level = match (score) {case 0 | 10 | 20 | 30 | 40 | 50 => "D" //【|】表示或case 60 => "C"case 70 | 80 => "B"case 90 | 100 => "A" // Matched.case _ => "Not a valid score"}println(level)
}

3.3 绑定模式(类似C#的var)

//用于匹配任何表达式,并将其结果分配给新的局部变量(捕获)
//注意:如果模式使用了【|】,则不能使用绑定模式
main() {let x = -10let y = match (x) {case 0 => "zero"case n => "x is not zero and x = ${n}" // Matched.}println(y)
}//上例在C#中的实现
class Program
{static void Main(string[] args){var x = -10;var y = x switch{0 => "zero",var n => $"x is not zero and x={n}"};Console.WriteLine(y);}
}

3.4 Tuple模式(类似C#的位置模式)

//下例中,同时使用了绑定模式和通配符
main() {let tv = ("Alice", 24)let s = match (tv) {case ("Bob", age) => "Bob is ${age} years old"case ("Alice", age) => "Alice is ${age} years old" // Matchedcase (name, 100) => "${name} is 100 years old"case (_, _) => "someone"}println(s)
}//注意,同一个Tuple中,不允许使用两个名称相同的绑定
case (x, x) => "someone" //报错

3.5 enum模式(C#中enum模式在常量模式中)

//在C#中,枚举是简单的常量值
//而在Cangjie中,枚举是代数数据类型,表现更加丰富
enum TimeUnit {| Year(UInt64)| Month(UInt64)
}
//通过模式匹配,解构T值
main() {let x = Year(2)let s = match (x) {case Year(n) => "x has ${n * 12} months" // Matched,并解构T值case TimeUnit.Month(n) => "x has ${n} months"}println(s)
}//枚举模式的嵌套,元组模式也可以
enum TimeUnit {| Year(UInt64)| Month(UInt64)
}enum Command {| SetTimeUnit(TimeUnit)| GetTimeUnit| Quit
}main() {let command = SetTimeUnit(Year(2022))match (command) {case SetTimeUnit(Year(year)) => println("Set year ${year}")case SetTimeUnit(Month(month)) => println("Set month ${month}")case _ => ()}
}

3.6 where(类似C#中的when)

enum RGBColor {| Red(Int16) | Green(Int16) | Blue(Int16)
}
main() {let c = RGBColor.Green(-100)let cs = match (c) {case Red(r) where r < 0 => "Red = 0"case Red(r) => "Red = ${r}"case Green(g) where g < 0 => "Green = 0" // Matched.case Green(g) => "Green = ${g}"case Blue(b) where b < 0 => "Blue = 0"case Blue(b) => "Blue = ${b}"}print(cs)
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot会员信息管理系统-计算机毕业设计源码38258

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3开发技术 1.3.1 Spring Boot框架 1.3.2 Java语言 1.3.3 MySQL数据库 1.4论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统功能分析 2.4 系统用例分析…

代码审计:Bluecms v1.6

代码审计&#xff1a;Bluecms v1.6 漏洞列表如下(共计32个漏洞&#xff0c;附Exp&#xff0c;按时间顺序)&#xff1a; 未完待续… 1、user.php 766行处存在任意文件删除漏洞 Exp:http://127.0.0.3/bluecms/user.php?actedit_user_info Post&#xff1a;face_pic32.php el…

动静资源的转发操作

目录 Nginx中的location指令 静态资源的转发 动态资源的转发 注意事项 深入研究 如何在Nginx中实现对特定后缀文件的静态资源进行反向代理&#xff1f; Nginx中location指令的优先级是怎样确定的&#xff1f; 为什么在使用proxy_pass时要区分是否带有斜杠&#xff1f; N…

《Java初阶数据结构》----8.<java对象的比较总结>

目录 前言 一、Java对象的比较 1.1基本类型的比较 1.2 对象比较的问题&#xff08;与equals&#xff09; 1.3对象的比较 &#xff08;三种常用方式&#xff09; 1.重写equals方法 2.基于Comparble接口类的比较 3.基于比较器比较&#xff08;Comparator接口&#xff09; …

秒懂C++之string类(下)

目录 一.接口说明 1.1 erase 1.2 replace&#xff08;最好别用&#xff09; 1.3 find 1.4 substr 1.5 rfind 1.6 find_first_of 1.7 find_last_of 二.string类的模拟实现 2.1 构造 2.2 无参构造 2.3 析构 2.4.【】运算符 2.5 迭代器 2.6 打印 2.7 reserve扩容 …

大模型算法面试题(十二)

本系列收纳各种大模型面试题及答案。 1、领域模型Continue PreTrain数据如何选取 在领域模型的Continue PreTrain&#xff08;持续预训练&#xff09;过程中&#xff0c;数据选取是一个至关重要的步骤&#xff0c;它直接影响模型在特定领域上的性能和泛化能力。以下是一些关于…

react native FlatList 组件滚动问题

版本"react-native": "0.74.2", <FlatListstyle{{width: 100%}}ref{flatListRef}data{list}renderItem{chatItem}keyExtractor{item > item.id}// onScroll{handleScroll}onContentSizeChange{() > {// 内容大小变化时&#xff0c;如果未手动滚动…

JavaScript在现代Web开发中的高级特性与趋势

介绍随着Web技术的飞速发展&#xff0c;JavaScript的角色日益重要&#xff0c;不仅限于前端逻辑处理&#xff0c;还涉及到后端服务、移动应用等多个领域。阐述掌握JavaScript高级特性对于开发高性能、可扩展Web应用的重要性。 1. ES6新特性概览 箭头函数&#xff1a;更简洁的…

Transformer-Bert---散装知识点---mlm,nsp,较之经典tran的区别和实际应用方式

本文记录的是笔者在了解了transformer结构后嗑bert中记录的一些散装知识点&#xff0c;有时间就会整理收录&#xff0c;希望最后能把transformer一个系列都完整的更新进去。 1.自监督学习 bert与原始的transformer不同&#xff0c;bert是使用大量无标签的数据进行预训练&#…

batch norm记录

文章目录 概要整体架构流程训练阶段推理阶段模型中使用的注意事项 概要 面试百度时候被问到了BN 内部详细的训练阶段&#xff0c;推理阶段的计算过程。没回答好&#xff0c;来记录一下 推荐一下b站up: Enzo_Mi。视频做的确实不错 bn 讲解视频 整体架构流程 训练阶段 均值和标…

【C/C++】printf和cout的区别

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

【公式解释】《系统论》《控制论》《信息论》的共同重构:探索核心公式与深度解析

《系统论》《控制论》《信息论》的共同重构:探索核心公式与深度解析 关键词:系统论、控制论、信息论、状态空间方程、系统矩阵。 Keywords: System theory, Control theory, Information theory, State-space equations, System matrices. 核心公式与三论共同之处 在系统…

C++初阶学习——探索STL奥秘——标准库中的string类

1. 为什么学习string类&#xff1f; 在我们学习C语言的时候&#xff0c;有一个点是非常难处理的&#xff0c;那就是字符串&#xff0c;在我们对字符串访问&#xff0c;增删查改时都是非常不便的&#xff0c;所以我们封装了一个string类主要来处理字符串有关的问题 2. 标准库中…

嵌入式硬件面试题集萃:从基础到进阶

基础问题 问题: 解释什么是微控制器&#xff0c;以及它与微处理器的区别。 答案: 微控制器是具有集成内存和输入/输出外设的微型计算机。与通用微处理器相比&#xff0c;微控制器通常用于控制特定应用&#xff0c;而不是执行通用计算任务。 问题: 什么是数字逻辑门&#xff0c…

多模态论文一:CLIP模型主要内容讲解【原理+代码】

一、CLIP模型主要内容讲解 CLIP&#xff08;Contrastive Language-Image Pre-training&#xff09;是OpenAI在2021年发布的一种用于图像和文本联合表示学习的模型。CLIP的核心思想是通过对比学习来预训练一个模型&#xff0c;使其能够理解图像和文本之间的关系。以下是CLIP的工…

49、PHP 实现堆排序

题目&#xff1a; PHP 实现堆排序 描述&#xff1a; 堆排序基本思想:堆排序(HeapSort)是一树形选择排序。在排序过程中&#xff0c;将R[l…n]看成是一棵完全二叉树的顺序存储结构&#xff0c;利用完全二叉树中双亲结点和孩子结点之间的内在关系&#xff0c;在当前无序区中选择…

代码打包大师班:掌握PyInstaller,发布无阻

安装PyInstaller&#xff1a;打包之旅的起点 首先&#xff0c;确保你的Python开发环境已就绪&#xff0c;然后借助pip这位全能助手&#xff0c;安装PyInstaller。打开命令行&#xff0c;键入以下指令&#xff0c;耐心等待安装完成&#xff1a; pip install pyinstallerPyInst…

C++20之设计模式(22):策略模式

策略模式 策略模式动态策略静态策略总结 策略模式 假设您决定使用包含多个字符串的数组或向量&#xff0c;并将它们作为列表输出 ["just", "like", "this"]。 如果考虑不同的输出格式&#xff0c;您可能知道需要获取每个元素&#xff0c;并将其…

数据传输安全--SSL VPN

目录 IPSEC在Client to LAN场景下比较吃力的表现 SSL VPV SSL VPN优势 SSL协议 SSL所在层次 SSL工作原理 SSL握手协议、SSL密码变化协议、SSL警告协议三个协议作用 工作过程 1、进行TCP三次握手、建立网络连接会话 2、客户端先发送Client HELLO包&#xff0c;下图是包…

Oracle对比两表数据的不一致

MINUS 基本语法如下 [SQL 语句 1] MINUS [SQL 语句 2];举个例子&#xff1a; select 1 from dual minus select 2 from dual--运行结果 1-------------------------------- select 2 from dual minus select 1 from dual--运行结果 2所以&#xff0c;如果想找所有不一致的&a…