rust模式

一、模式是什么

模式是Rust中特殊的语法,它用来匹配值

二、模式的使用场景

(一)match
match的每个分支箭头左边部分就是模式。

match VALUE {PATTERN => EXPRESSION,PATTERN => EXPRESSION,PATTERN => EXPRESSION,
}

例子

match x {None => None,Some(i) => Some(i + 1),
}

箭头左边的None和Some(i)就是模式。

(二)if let

例子

fn main() {let favorite_color: Option<&str> = None;let is_tuesday = false;let age: Result<u8, _> = "34".parse();if let Some(color) = favorite_color {println!("Using your favorite color, {color}, as the background");} else if is_tuesday {println!("Tuesday is green day!");} else if let Ok(age) = age {if age > 30 {println!("Using purple as the background color");} else {println!("Using orange as the background color");}} else {println!("Using blue as the background color");}
}

if let后面的Some(color) 和 Ok(age)就是模式。
如果用户指定了中意的颜色,就使用它。如果没有指定且今天是星期二,就使用绿色。如果用户指定了他们的年龄并能够成功解析为数字的话,我们将根据这个数字使用紫色或者橙色。最后,如果没有一个条件符合,就使用蓝色。

(三)while let

例子

let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop() {println!("{}", top);
}

while let后面的Some(top) 就是模式。
pop方法取出vector的最后一个元素并返回Some(value)。如果vector是空的,它返回None。while循环只要pop返回Some就会一直运行其块中的代码。一旦其返回None,while循环停止。我们可以使用while let来弹出栈中的每一个元素。

(四)for

例子

let v = vec!['a', 'b', 'c'];
for (index, value) in v.iter().enumerate() {println!("{} is at index {}", value, index);
}
运行结果
a is at index 0
b is at index 1
c is at index 2

(index, value)就是模式
enumerate方法返回一个元组,元组元素分别是索引和值。第一个是元组 (0, ‘a’)。当这个值匹配模式 (index, value)时,index将会是0而value将会是 ‘a’

(五)let

let PATTERN = value;

例子

let x = 5;

x就是一个模式。

let (x, y, z) = (1, 2, 3);

(x, y, z) 也是一个模式。Rust会比较值 (1, 2, 3) 与模式 (x, y, z) 并发现此值匹配这个模式。在这个例子中,将会把1绑定到x,2绑定到y并将3绑定到z。
如果模式中元素的数量不匹配值中元素的数量,则整个类型不匹配,并会得到一个编译错误。

let (x, y) = (1, 2, 3);

一个错误的模式结构

(六)函数参数
函数参数也可以是模式。
例子

fn foo(x: i32) {// code goes here
}

x就是一个模式!类似于let中的模式。

fn print_coordinates(&(x, y): &(i32, i32)) {println!("Current location: ({}, {})", x, y);
}
fn main() {let point = (3, 5);print_coordinates(&point);
}

这会打印出Current location: (3, 5)。值 &(3, 5) 会匹配模式 &(x, y),如此x得到了值3,而y得到了值5。

(七)闭包参数
闭包参数也可以是模式。与函数参数一样。

三、refutable与irrefutable模式的区别

模式有两种:refutable(可反驳的)和irrefutable(不可反驳的)。
能匹配任何值的模式称为不可反驳的(irrefutable)。一个例子是let x = 5; 语句中的x,因为x可以匹配任何值所以不可能会失败。
不能匹配任何值的的模式称为可反驳的(refutable)。一个例子是if let Some(x) = a_value表达式中的Some(x);如果变量a_value中的值是None,那么Some(x) 模式不能匹配。

函数参数、let、for只能使用不可反驳的模式
if let和while let只能使用可反驳的模式,因为根据定义他们意在处理可能的失败:条件表达式的功能就是根据成功或失败执行不同的操作。

let Some(x) = some_option_value;

尝试在let中使用可反驳模式,编译错误
Some(x)是可反驳的。如果some_option_value的值是None,其不会匹配模式Some(x)。
可以使用if let。如此,如果模式不匹配,大括号中的代码将被忽略,其余代码保持有效。

if let Some(x) = some_option_value {println!("{}", x);
}

尝试把不可反驳模式用到if let上,编译器会给出一个警告:

if let x = 5 {println!("{}", x);
};

match必须使用可反驳模式,除了最后一个分支需要使用能匹配任何剩余值的不可反驳模式。

四、模式语法

(一)字面量模式

句法
LiteralPattern :BOOLEAN_LITERAL| CHAR_LITERAL| BYTE_LITERAL| STRING_LITERAL| RAW_STRING_LITERAL| BYTE_STRING_LITERAL| RAW_BYTE_STRING_LITERAL| -? INTEGER_LITERAL

字面量模式能匹配字面量。
字面量模式总是可反驳型的。

示例:

for i in -2..5 {match i {-1 => println!("It's minus one"),1 => println!("It's a one"),2|4 => println!("It's either a two or a four"),_ => println!("Matched none of the arms"),}
}

-1、1、2、4都是字面量模式

(二)标识符模式

句法
IdentifierPattern :ref? mut? IDENTIFIER (@ Pattern ) ?

标识符模式只能包含一个标识符,能匹配任何值,并将值绑定到该标识符上。
标识符模式总是不可反驳型的。
最常见的标识符模式应用场景就是用在let上和函数(包括闭包)的参数上。

let mut variable = 10;
fn sum(x: i32, y: i32) -> i32 {

默认情况下,标识符模式里变量会和匹配到的值的一个副本绑定,或值自身移动过来和变量绑定,具体是使用拷贝语义还是移动语义取决于匹配到的值是否实现了 Copy。也可以使用关键字ref将变量和值的引用绑定,或者使用ref mut将变量和值的可变引用绑定。示例:

match a {None => (),Some(value) => (),
}
match a {None => (),Some(ref value) => (),
}

在第一个匹配表达式中,值被拷贝或移动到变量value上。在第二个匹配中,值的引用被绑定到变量上。之所以需要这种句法,是因为在解构时,操作符 & 不能应用在值的字段上。例如,以下内容无效:

if let Person { name: &person_name, age: 18..=150 } = value { }

要使其有效,请按如下方式编写代码:

if let Person { name: ref person_name, age: 18..=150 } = value { }

这里,ref不是被匹配的一部分。它唯一的目的就是使变量和匹配值的引用绑定起来,而不是潜在地拷贝或移动匹配到的内容。

@ 模式
@允许我们在创建一个变量的同时测试其值是否匹配模式。使用 @ 可以在一个模式中同时测试和保存变量值。
示例

enum Message {Hello { id: i32 },
}
let msg = Message::Hello { id: 5 };
match msg {Message::Hello { id: id_variable @ 3..=7,} => println!("Found an id in range: {}", id_variable),Message::Hello { id: 10..=12 } => {println!("Found an id in another range")}Message::Hello { id } => println!("Found some other id: {}", id),
}

上例会打印出Found an id in range: 5。
第一个分支只有id的值在3到7之间,才匹配此模式,才将id的值赋给id_variable。
第二个分支只在模式中指定了一个范围,id字段的值可以是10、11或12,不过这个分支不能使用id的值,因为没有将id值保存进一个变量。
最后一个分支使用了结构体字段简写语法,此分支没有测试,任何值都会匹配此分支。因此可以使用id的值。

(三)通配符模式

句法
WildcardPattern :_

通配符模式(下划线符号)能与任何值匹配。常用它来忽略那些无关紧要的值。在其他模式中使用该模式时,它匹配单个数据字段(与和匹配所有其余字段的..相对)。与标识符模式不同,它不会复制、移动或借用它匹配的值。
通配符模式总是不可反驳型的。

示例:

let (a, _) = (10, x); // x一定会被 _ 匹配上
let real_part = |a: f64, _: f64| { a };// 忽略一个函数/闭包参数
let RGBA{r: red, g: green, b: blue, a: _} = color;// 忽略结构体的一个字段
if let Some(_) = x {}// 能接收带任何值的任何Some

(四)剩余模式

句法
RestPattern :..

剩余模式匹配之前之后没有匹配的零个或多个元素。它只能在元组模式、元组结构体模式、切片模式中使用,并且只能作为这些模式中的一个元素出现一次。当作为标识符模式的子模式时,它也可出现在切片模式里。
剩余模式总是不可反驳型的。

示例:

match value {[] => println!("slice is empty"),[one] => println!("single element {}", one),[head, tail @ ..] => println!("head={} tail={:?}", head, tail),//作为标识符模式的子模式
}
match slice {// 忽略除最后一个元素以外的所有元素,并且最后一个元素必须是 "!".[.., "!"] => println!("!!!"),// `start` 是除最后一个元素之外的所有元素的一个切片,最后一个元素必须是 “z”。[start @ .., "z"] => println!("starts with: {:?}", start),// `end` 是除第一个元素之外的所有元素的一个切片,第一个元素必须是 “a”["a", end @ ..] => println!("ends with: {:?}", end),rest => println!("{:?}", rest),
}
if let [.., penultimate, _] = slice {println!("next to last is {}", penultimate);
}
// 剩余模式也可是在元组和元组结构体模式中使用。
match tuple {(1, .., y, z) => println!("y={} z={}", y, z),(.., 5) => println!("tail must be 5"),(..) => println!("matches everything else"),
}

(五)区间模式

句法
RangePattern :RangePatternBound ..= RangePatternBound
RangePatternBound :CHAR_LITERAL| BYTE_LITERAL| -? INTEGER_LITERAL| PathInExpression| QualifiedPathInExpression

区间模式匹配封闭区间内的值。例如,一个模式'm'..='p'将只能匹配值’m’、‘n’、‘o’ 和 ‘p’。它的边界值可以是字面量,也可以是指向常量值的路径。
一个模式a ..= b必须总是a≤b。例如,10..=0这样的区间模式是错误的。
区间模式只适用于标量类型。可接受的类型有:

整型(u8、i8、u16、i16、usize、isize ...)。
字符型(char)。

示例:

let valid_variable = match c {'a'..='z' => true,'A'..='Z' => true,'α'..='ω' => true,_ => false,
};
println!("{}", match ph {0..=6 => "acid",7 => "neutral",8..=14 => "base",_ => unreachable!(),
});
// 使用指向常量值的路径:
println!("{}", match altitude {TROPOSPHERE_MIN..=TROPOSPHERE_MAX => "troposphere",STRATOSPHERE_MIN..=STRATOSPHERE_MAX => "stratosphere",MESOSPHERE_MIN..=MESOSPHERE_MAX => "mesosphere",_ => "outer space, maybe",
});
if let size @ binary::MEGA..=binary::GIGA = n_items * bytes_per_item {println!("这适用并占用{}个字节", size);
}
// 使用路径:
println!("{}", match 0xfacade {0 ..= <u8 as MaxValue>::MAX => "fits in a u8",0 ..= <u16 as MaxValue>::MAX => "fits in a u16",0 ..= <u32 as MaxValue>::MAX => "fits in a u32",_ => "too big",
});

当区间模式匹配某(非usize和 非isize)整型类型和字符型(char)的整个值域时,此模式是不可反驳型的。例如,0u8..=255u8是不可反驳型的。某类整型的值区间是从该类型的最小值到该类型最大值的闭区间。字符型(char)的值的区间就是那些包含所有Unicode标量值的区间,即 '\u{0000}'..='\u{D7FF}''\u{E000}'..='\u{10FFFF}'

(六)引用模式

句法
ReferencePattern :(&|&&) mut? PatternWithoutRange

引用模式对匹配到的指针做解引用
例如,下面两个匹配是等效的:

let int_reference = &3;
let a = match *int_reference { 0 => "zero", _ => "some" };
let b = match int_reference { &0 => "zero", _ => "some" };
assert_eq!(a, b);

引用模式要求必须使用&& 来匹配对引用的引用,因为 && 本身是一个单独的token,而不是两个 token。
举例

let a = Some(&&10);
match a {Some( &&value ) => println!("{}", value),None => {}
}

引用模式中添加关键字mut可对可变引用做解引用。引用模式中的可变性标记必须与值的引用的可变性匹配。
引用模式总是不可反驳型的。

(七)结构体模式

句法
StructPattern :PathInExpression {StructPatternElements ?}
StructPatternElements :StructPatternFields (, | , StructPatternEtCetera)?| StructPatternEtCetera
StructPatternFields :StructPatternField (, StructPatternField) *
StructPatternField :OuterAttribute *(TUPLE_INDEX : Pattern| IDENTIFIER : Pattern| ref? mut? IDENTIFIER)
StructPatternEtCetera :OuterAttribute *..

结构体模式匹配结构体值。它也被用来解构结构体。
在结构体模式中,结构体字段需通过名称、索引(对于元组结构体来说)来指代,或者通过使用..来忽略:

match s {Point {x: 10, y: 20} => (),Point {y: 10, x: 20} => (), // 顺序没关系Point {x: 10, ..} => (),Point {..} => (),
}
match t {PointTuple {0: 10, 1: 20} => (),PointTuple {1: 10, 0: 20} => (), // 顺序没关系PointTuple {0: 10, ..} => (),PointTuple {..} => (),
}
如果没使用 ..,需要提供所有字段的详尽匹配:
match struct_value {Struct{a: 10, b: 'X', c: false} => (),Struct{a: 10, b: 'X', ref c} => (),Struct{a: 10, b: 'X', ref mut c} => (),Struct{a: 10, b: 'X', c: _} => (),Struct{a: _, b: _, c: _} => (),
}

IDENTIFIER能匹配任意值,并将其绑定到变量上。

let Struct{a: x, b: y, c: z} = struct_value; // 解构所有的字段

当一个结构体模式的子模式是可反驳型的,那这个结构体模式就是可反驳型的。

解构结构体

struct Point {x: i32,y: i32,
}
fn main() {let p = Point { x: 0, y: 7 };let Point { x: a, y: b } = p;assert_eq!(0, a);assert_eq!(7, b);
}
或者
struct Point {x: i32,y: i32,
}
fn main() {let p = Point { x: 0, y: 7 };let Point { x, y } = p;assert_eq!(0, x);assert_eq!(7, y);
}

这段代码创建了变量x和y,与变量p中的x和y相匹配。其结果是变量x和y包含结构体p中的值。
也可以使用字面值作为结构体模式的一部分进行解构,而不是为所有的字段创建变量。这允许我们测试一些字段为特定值的同时创建其他字段的变量。
例子

fn main() {let p = Point { x: 0, y: 7 };match p {Point { x, y: 0 } => println!("On the x axis at {x}"),Point { x: 0, y } => println!("On the y axis at {y}"),Point { x, y } => {println!("On neither axis: ({x}, {y})");}}
}

第一个分支通过指定字段y匹配字面值0来匹配任何位于x轴上的点。此模式仍然创建了变量x以便在分支的代码中使用。
第二个分支通过指定字段x匹配字面值0来匹配任何位于y轴上的点,并为字段y创建了变量y。
第三个分支没有指定任何字面值,所以其会匹配任何其他的Point并为x和y两个字段创建变量。
在这个例子中,值p因为其x包含0而匹配第二个分支,因此会打印出On the y axis at 7。
记住match表达式一旦找到一个匹配的模式就会停止检查其它分支,所以即使Point { x: 0, y: 0} 在x轴上也在y轴上,这些代码也只会打印On the x axis at 0。

(八)元组结构体模式

句法
TupleStructPattern :PathInExpression ( TupleStructItems? )
TupleStructItems :Pattern ( , Pattern )* ,?

元组结构体模式匹配元组结构体值和枚举值。它还被用于解构元组结构体值或枚举值。
当元组结构体模式的一个子模式是可反驳型的,则该元组结构体模式就是可反驳型的。

(九)元组模式

句法
TuplePattern :( TuplePatternItems? )
TuplePatternItems :Pattern ,| RestPattern| Pattern (, Pattern)+ ,?

元组模式匹配元组值。它们还被用来解构元组值。
内部只带一个剩余模式的元组模式(..) 可以匹配任意长度的元组。
当元组模式的一个子模式是可反驳型的,那该元组模式就是可反驳型的。
使用元组模式的示例:

let pair = (10, "ten");
let (a, b) = pair;
assert_eq!(a, 10);
assert_eq!(b, "ten");

(十)切片模式

句法
SlicePattern :[ SlicePatternItems? ]
SlicePatternItems :Pattern (, Pattern)* ,?

切片模式可以匹配固定长度的数组和动态长度的切片。

// 固定长度
let arr = [1, 2, 3];
match arr {[1, _, _] => "从1开始",[a, b, c] => "从其他值开始",
};// 动态长度
let v = vec![1, 2, 3];
match v[..] {[a, b] => { /* 这个分支不适用,因为长度不匹配 */ }[a, b, c] => { /* 这个分支适用 */ }_ => { /* 这个通配符是必需的,因为长度不是编译时可知的 */ }
};

在匹配数组时,只要每个元素是不可反驳型的,切片模式就是不可反驳型的。当匹配切片时,只有单个..或带有 ..作为子模式的标识符模式的情况才是不可反驳型的。

(十一)路径模式

句法
PathPattern :PathInExpression| QualifiedPathInExpression

路径模式是指向常量值或指向没有字段的结构体或没有字段的枚举变体的模式。

非限定路径模式可以指向:

枚举变体
结构体
常量
关联常量

限定路径模式只能指向关联常量。
常量不能是联合体类型。结构体常量和枚举常量必须带有 #[derive(PartialEq, Eq)] 属性(不只是实现)。
当路径模式指向结构体或枚举变体(枚举只有一个变体)或类型为不可反驳型的常量时,该路径模式是不可反驳型的。当路径模式指向的是可反驳型常量或带有多个变体的枚举时,该路径模式是可反驳型的。

解构枚举

enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),
}
fn main() {let msg = Message::ChangeColor(0, 160, 255);match msg {Message::Quit => {println!("The Quit variant has no data to destructure.");}Message::Move { x, y } => {println!("Move in the x direction {x} and in the y direction {y}");}Message::Write(text) => {println!("Text message: {text}");}Message::ChangeColor(r, g, b) => {println!("Change the color to red {r}, green {g}, and blue {b}",)}}
}

这段代码会打印出Change the color to red 0, green 160, and blue 255。尝试改变msg的值来观察其他分支代码的运行。
对于像Message::Quit这样没有任何数据的枚举成员,不能进一步解构其值。只能匹配其字面值Message::Quit,因此模式中没有任何变量。
对于像Message::Move这样的类结构体枚举成员,可以采用类似于匹配结构体的模式。在成员名称后,使用大括号并列出字段变量以便将其分解以供此分支的代码使用。这里使用了示例18-13所展示的简写。
对于像Message::Write这样的包含一个元素,以及像Message::ChangeColor这样包含三个元素的类元组枚举成员,其模式则类似于用于解构元组的模式。模式中变量的数量必须与成员中元素的数量一致。

解构嵌套的结构体和枚举
目前为止,所有的例子都只匹配了深度为一级的结构体或枚举,不过当然也可以匹配嵌套的项!例如,

enum Color {Rgb(i32, i32, i32),Hsv(i32, i32, i32),
}
enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(Color),
}
fn main() {let msg = Message::ChangeColor(Color::Hsv(0, 160, 255));match msg {Message::ChangeColor(Color::Rgb(r, g, b)) => {println!("Change color to red {r}, green {g}, and blue {b}");}Message::ChangeColor(Color::Hsv(h, s, v)) => {println!("Change color to hue {h}, saturation {s}, value {v}")}_ => (),}
}

第一个分支的模式匹配一个包含Color::Rgb枚举成员的Message::ChangeColor枚举成员,然后模式绑定了3个内部的i32值。
第二个分支的模式也匹配一个Message::ChangeColor枚举成员,但是其内部的枚举会匹配Color::Hsv枚举成员。
我们可以在一个match表达式中指定这些复杂条件,即使会涉及到两个枚举。

(十二)分组

句法
GroupedPattern :( Pattern )

将模式括在圆括号内可用来显式控制模式的优先级。例如,像 &0..=5这样的引用模式和区间模式相邻就会引起歧义,这时可以用圆括号来消除歧义。

let int_reference = &3;
match int_reference {&(0..=5) => (),_ => (),
}

(十三)并列
pattern | pattern
匹配两个或多个并列子模式(例如:A | B | C)中的一个的模式。除了let绑定和函数参数(包括闭包参数),可以在任何场景使用

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

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

相关文章

3.3 使用广播信道的数据链路层

思维导图&#xff1a; 3.3.1 局域网的数据链路层 ### 3.3 使用广播信道的数据链路层 #### 简介 - 广播信道支持一对多通信。 - 局域网技术在20世纪70年代末兴起&#xff0c;现在在计算机网络中占有主导地位。 #### 3.3.1 局域网的数据链路层 **局域网的特点&#xff1a;** 1…

9-AJAX-上-原理详解

一、定义 1、什么是Ajax Ajax&#xff1a;即异步 JavaScript 和XML。Ajax是一种用于创建快速动态网页的技术。通过在后台与进行少量数据交换&#xff0c;Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下&#xff0c;对网页的某部分进行更新。而传统的…

储存数据文本json的读写

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、json文本介绍二、json文本的应用三、json文本的操作1、环境配置2、写入文件3、读取文件4、文件格式解析注意的点参考链接前言 认知有限,望大家…

FairGuard游戏加固无缝兼容 Android 14 正式版

北京时间10月4日&#xff0c;谷歌公司在“Made by Google 2023”硬件发布会上公开了新版安卓操作系统—— Android 14 正式版。 为保证产品的加固效果并提供更优质的服务&#xff0c;FairGuard游戏加固团队第一时间组织人员进行了相关测试。 据测试&#xff0c;FairGuard游戏…

架构师选择题--计算机网络

架构师选择题--计算机网络 22年考题21年考题20年考题19年真题2017考题 22年考题 d http:80 https:httpssl &#xff1a;443 b b pop3是邮件接收协议&#xff1a;110 SMTP是邮件发送协议&#xff1a;25 http:80 A 网络隔离&#xff1a;防火墙&#xff08;逻辑&#xff09;&…

聊聊JDK19特性之虚拟线程 | 京东云技术团队

1.前言 在读《深入理解JVM虚拟机》这本书前两章的时候整理了JDK从1.0到最新版本发展史&#xff0c;其中记录了JDK这么多年来演进过程中的一些趣闻及引人注目的一些特性&#xff0c;在调研JDK19新增特性的时候了解到了虚拟线程这个概念&#xff0c;于是对虚拟线程进行学习整理内…

APK大小缩小65%,内存减少70%:如何优化Android App

APK大小缩小65&#xff05;&#xff0c;内存减少70&#xff05;&#xff1a;如何优化Android App 我们一直在努力为我们的Android应用程序构建MVP产品。在开发MVP产品后&#xff0c;我们发现需要进行应用程序优化以提高性能。经过分析&#xff0c;我们发现了以下可以改进的应用…

如何选择编程语言Python Go还是Rust?

选择编程语言需要考虑多个方面&#xff0c;包括语言的特性、社区支持、工作机会、学习曲线等。下面是关于Python Go和Rust的一些介绍。 1.基本语法 1. Python: Python 是一种脚本语言&#xff0c;以简洁、易读的语法著称。以下是 Python 的基本语法示例&#xff1a; # Hello…

提取log文件中的数据,画图

要提取的log格式如下&#xff1a; 代码如下&#xff1a; import reimport matplotlib.pyplot as plt import numpy as npimport argparse from os import path from re import searchclass DataExtractor(object): DataExtrator class def __init__(self, infile, keyword, out…

Docker基本操作【一篇学会项目部署】

文章目录 一、Docker简介二、Docker安装三、配置镜像加速四、Docker部署五、Docker基础操作1. 常见命令2. 操作演示3. 数据卷①nginx的html目录挂载②分析匿名数据卷③MySQL的本地目录挂载 4. 自定义镜像①Dockerfile②构建镜像 5. 网络①常见命令②自定义网络 六、DockerCompo…

乐优商城(二)搭建后台前端

1. 搭建后台管理前端 1.1 导入已有资源 找到已经准备好的 leyou-manage-web 压缩文件&#xff0c;这就是后台管理的前端项目 解压 leyou-manage-web 文件到项目中&#xff0c;注意与 leyou 文件同级 1.2 安装依赖 在 IDEA 中打开 leyou-manage-web 工程 2.打开 Teminal&…

Windows 下 Qt 可执行程序添加默认管理员权限启动(QMAKE、MinGW MSVC)

记录 Qt/QMAKE 为可执行程序添加管理员权限 MSVC Windows下 MSVC 套件地位超然&#xff0c;只需要在 .pro 文件中加入&#xff1a; QMAKE_LFLAGS /MANIFESTUAC:\"level\requireAdministrator\ uiAccess\false\\"重新构建 MinGW 与MSVC相比&#xff0c;MinGW所需…

2023年中国医学影像信息系统市场规模、竞争格局及行业趋势分析[图]

医学影像信息系统简称PACS&#xff0c;与临床信息系统、放射学信息系统、医院信息系统、实验室信息系统同属医院信息系统。医学影像信息系统是处理各种医学影像信息的采集、存储、报告、输出、管理、查询的计算机应用程序。主要包括&#xff1a;预约管理、数据接收、影像处理、…

如何开始学习量子机器学习

一、关于量子计算 这是我关于量子机器学习&#xff08;QML&#xff09;的第二篇文章&#xff0c;这是第一篇&#xff0c;关于为什么你应该开始学习QML。 开始研究量子机器学习很困难&#xff0c;因为我不知道我需要了解多少量子力学和计算知识。我在101年上大学时上了量子力学2…

【Pytorch】深度学习之数据读取

数据读入流程 使用DatasetDataLoader完成Pytorch中数据读入 Dataset定义数据格式和数据变换形式 DataLoader用iterative的方式不断读入批次数据&#xff0c;实现将数据集分为小批量进行训练 使用PyTorch自带数据集 使用Dataset完成数据格式和数据变换的定义 import torch fro…

腾讯云短信验证登录

提前准备工作 1.已 注册腾讯云 账号&#xff0c;并完成 企业实名认证。 2.已 购买 短信套餐包。 3.准备短信签名归属方资质证明文件 4.已获取短信应用的 SDKAppID。 主要获取这几个参数 secretId(秘钥id) secretKey(秘钥key) SmsSdkAppId(appId) TemplateId(短信模板i…

数字人直播软件排名推荐,铭顺科技数字人品牌抢占“日不落”流量新技能

在今年的618中&#xff0c;相信大家能明显感受到&#xff0c;现如今已经有越来越多的品牌商都在使用AI营销工具&#xff0c;如AI营销工具、AI电话、AI虚拟主播。据京东战报显示&#xff0c;在今年的618中&#xff0c;使用AI数字人直播比去年双11增幅近5倍。 7*24小时不间断直播…

Android:自定义原生TimePickerDialog样式

效果图&#xff1a; 目标效果图&#xff1a; 原生效果&#xff1a; 实现&#xff1a; 首先是Dialog样式&#xff1a; <style name"TimePickerDialogStyle" parent"style/Theme.AppCompat.DayNight.Dialog.Alert"><item name"android:time…

Nosql redis高可用和持久化

Nosql redis高可用和持久化 1、redis高可用2、redis持久化2.1redis持久化2.2Redis 持久化方法2.3RDB 持久化2.3.1RDB持久化工作原理2.3.2触发条件2.3.3其他自动触发机制2.3.4执行流程2.3.5启动时加载 2.4AOF 持久化2.4.1AOF持久化原理2.4.2开启AOF2.4.3执行流程2.4.4文件重写的…

逆向开发C#调用Java 方法

引言 开发过程中,我们经常遇到这种情况。就是各种语言转换,比如有一段Java 加密代码需要转换成c# ,或者Java代码转换成Python。 可选方案包括:1, 自己手动改,调试。2,使用AI 自动转换,我尝试过,简单的代码可以转换。3, c# 调用Java 代码,假如Java代码还包含好多mave…