Rust 快速入门60分① 看完这篇就能写代码了
Rust 一门赋予每个人构建可靠且高效软件能力的语言https://hannyang.blog.csdn.net/article/details/130467813?spm=1001.2014.3001.5502关于Rust安装等内容请参考上文链接,写完上文就在考虑写点关于Rust的入门文章,本专辑将直接从Rust基础入门内容开始讲起。标题《快速入门60分》并不指60分钟,而是希望自己写完这个专辑后,可以得个60分,也能掌握Rust60%上下的内容,请看第一章《变量与常量》:
目录
一、变量与常量
1.1 变量
1.1.1. 变量命名
1.1.2. 变量声明、赋值
1.1.3. Snake case
1.1.4. 禁止使用和避免使用
1.1.5 匿名变量
1.2 基本数据类型
1.2.1 整型
1.2.2 浮点型
1.2.3 字符型
1.2.4 布尔型
1.3 变量的可变和不可变
1.3.1 不可变变量
1.3.2 可变变量
1.3.3 变量遮蔽
1.3.4 静态变量(全局变量)
1.4 常量
1.4.1 常量命名
1.4.2 常量用法
1.4.3 标准库常量
1.5 本章小结
一、变量与常量
1.1 变量
1.1.1. 变量命名
变量名由字母、数字或下划线组成,应该具有描述性,能够清楚地表达变量的含义。命名的基本规则和大多数编程语言基本相同,有些细节上稍微有所不同。规则如下:
- 变量名必须以字母或下划线开头。
- 变量名不能以数字开头。
- 变量名区分大小写,推荐使用 snake_case 规则(字母全部小写和下划线)。
- 禁止使用和 Rust 关键字同名的变量名。
- 避免使用和 Rust 标准库中已有的函数、类型或模块同名的变量名。
- 对于私有变量 (private variables),可以使用 _ 作为前缀,区分开公共变量和私有变量。
1.1.2. 变量声明、赋值
Rust 变量声明使用 let 关键字,有些早期版本的basic语言也用LET(现在通常是DIM)。
示例:
fn main() {let x = 323;let y = 3.23;print!("x: {}, ", x);println!("y: {}", y);//输出 x: 323, y: 3.23
}
上面示例中,fn 是函数 function 的缩写,表示 main() 是这个rust程序的主函数;
let 变量名 = 常数;就是一个变量声明、赋值语句;
print!() 和 println!() 是打印的“宏”,宏不是函数,但功能也就相近于Java中的System.out.print()函数和System.out.println()函数的功能,两者输出差一个换行符。
// 表示注释语句,注释与C++相同,行注释用 //,块注释用 /* */;Rust另外还有文档注释。
函数体中每一行都是一个语句(当然语句也可以跨多行表达),语句由各种表达式组成。第一条语句必须有标点符号分号作结尾,表达式一般没有符号作结尾的。关于Rust中的“宏”,它和C/C++中的“宏”还是不同的,更多函数相关内容,放到之后的函数章节再讲。
let 语句也可以分成两行,先声明再分配值(赋值绑定):
fn main() {let x;x = 100;println!("x: {}", x);
}
let 语句还可以一行赋值多个变量,但要加上括号(其实是复合数据类型之一的元组):
fn main() {let (x, y) = (3, 4);let z = (x*x+y*y) as f64;let z = z.sqrt().round() as i32;println!("{},{},{}", x, y, z); // 3,4,5let (a, b, c) = (1, 2, 3);println!("{},{},{}", a, b, c); // 1,2,3
}
其中,as 也是Rust关键字之一,在这里用于强制转换数据类型。
sqrt()、round() 分别为平方根、取整函数。
1.1.3. Snake case
Snake case 是一种命名规范,它使用小写字母,单词之间用下划线 "_" 连接。
Rust不推荐在变量中有大写字母,示例如下:
fn main() {let Int = 100;let My_Integer = 200;let my_integer = 300;println!("{} {} {}", Int, My_Integer, my_integer)
}
以上代码可以编译执行,但会有警告出现:
···Rust
warning: variable `Int` should have a snake case name
--> D:\Rust\hello.rs:2:9
|
2 | let Int = 100;
| ^^^ help: convert the identifier to snake case (notice the capitalization): `int`
|
= note: `#[warn(non_snake_case)]` on by default
warning: variable `My_Integer` should have a snake case name
--> D:\Rust\hello.rs:3:9
|
3 | let My_Integer = 200;
| ^^^^^^^^^^ help: convert the identifier to snake case: `my_integer`
warning: 2 warnings emitted
100 200 300
···
1.1.4. 禁止使用和避免使用
变量命名使用关键字,报错通不过编译,所以是禁止使用;但与标准库中已有的函数、类型同名,只是容易混淆,但编译不警告不报错,所以只能说是避免使用。如:
fn main() {//let fn = 10; //禁止使用//let let = 2; //禁止使用let u8 = 10u8; //避免使用let pow; //避免使用pow = u8.pow(2);println!("{} {}", u8, pow) //输出 10 100
}
其中, u8 的变量类型是8位无符号整型,pow() 是标准库函数平方幂函数。
函数名、类型名称作变量名不会报错,而fn, let关键字作变量名则报错:
```Rust
expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
```
1.1.5 匿名变量
下划线 _ 是一个特殊的变量名,更确切地说是变量名称的缺失,就称它为匿名变量。它的基本意思是舍弃,可以理解为废纸篓,这个变量扔掉不要了,不能被再次调用。(Go, Python里也有 _ 用作匿名变量,但细节各不相同,而且在python里 “_ = 5;print(_)” 是合法的)
fn main() {let (a,_) = (6,2);println!("{}", a);//println!("{}", _); //报错^ `_` not allowed here
}
1.2 基本数据类型
1.2.1 整型
Rust整型 分为有符号整型(signed,标记 in)和无符号整型(unsigned,标记 un),区别在于数字是否有负数。带符号整型的安全存储范围为 -2^(n-1) 到 2^(n-1) - 1,无符号整型的安全存储范围为 0 到 2^n,n 为数据位长度,见下表:
位长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch 由系统构架而定 | isize | usize |
isize 和 usize 是根据系统架构决定的,例如带符号整型,如果系统是 64 位,类型为 i64,如果系统是 32 位,类型为 i32。(这和C++中的size_t类型相似)
指定类型和默认类型
变量声明时,可以先指定类型,再分配绑定数值,变量名后面使用冒号跟随类型来明确指定变量的类型,称为显式指定;Rust 是强类型语言,具有自动判断变量类型的能力,可理解为这是隐式指定。以下示例中声明的变量 z 并没有明确指定其具体类型,则默认为 i32 类型,这也是 Rust 的特性之一类型推断。
fn main() {let x: u8;x = 123;let y = -1000i64;let z = -323; //不指定类型,默认为i32println!("x: {}, y: {}, z: {}", x, y, z);
}
1.2.2 浮点型
Rust浮点型 分为 32 位浮点数(f32)和 64 位浮点数(f64)。浮点型若不指定具体类型,则默认为 f64 浮点数,现在的高性能CPU对两种浮点数计算的速度几乎相同,但 64 位浮点数精度更高。
fn main() {let x: f32;x = 1.23;let y: f64 = 3.23;let z = -3.23; //不指定类型,默认为f64println!("x: {}, y: {}, z: {}", x, y, z);
}
1.2.3 字符型
Rust字符型 是一个4字节 Unicode 码,支持中文等非英文字符,使用单引号''包括。
fn main() {let a = 'a';let b: char = '字';let c = '😊';println!("a: {}, b: {}, c: {}", a, b, c);
}
1.2.4 布尔型
Rust布尔型 用 bool 表示,占用1个字节,值只能为 true 或 false,全小写非大写字母开头。(输出与声明同形,不像C/C++只能输出1和0)
fn main() {let x = true;let y: bool = false;println!("x: {}, y: {}", x, y); //输出 x: true, y: false
}
1.3 变量的可变和不可变
1.3.1 不可变变量
先看一个实例:
fn main() {let x = 6;x = x + 1; // 报错println!("{}", x)
}
在大多数编程语言中,上述实例应该打印出 7,但在Rust语言里却是报错:
```Rust
error[E0384]: cannot assign twice to immutable variable `x`
--> D:\Rust\hello.rs:3:5
|
2 | let x = 6;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | x = x + 1;
| ^^^^^^^^^ cannot assign twice to immutable variable
```
意思就是: 不能为不可变变量`x赋值两次`,并提示考虑绑定可变:`mut x`
特别之处: Rust变量是不可变的!
通常来说变量将是可变的,但是在 Rust 中预设变量却是不可变的。Rust 鼓励使用不可变变量,当然如果明确知道该变量是可变得,就得用关键字 mut 附加说明它是可变的变量。
1.3.2 可变变量
可变变量要用 let mut 两个关键字来声明,示例如下:
fn main() {let mut x = 6; // 可变变量声明要在let后附加mut关键字x = x + 1;println!("{}", x) // 输出 7
}
1.3.3 变量遮蔽
Rust可以定义一个与之前变量同名的新变量,称之为第一个变量被第二个 Shadowing 了,官方用的这个词 Shadowing,有时被翻译成隐藏有时被翻译成遮蔽,还有的翻译为重影。它的意思就是当使用相同变量的名称时,编译器将“看到”第二个变量。实际上,第二个变量 “遮蔽” 了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用 let 关键字来多次隐藏。总之,它和可变变量不是同一个概念。
fn main() {let x = 6;let x = x + 1;println!("{}", x); // 7let x = x * x;println!("{}", x); // 49
}
1.3.4 静态变量(全局变量)
静态变量用 static 声明的变量的生命周期是整个程序,从启动到退出。这也是Rust中唯一的声明全局变量的方法。它的生命周期永远是'static, 它占用的内存空间也不会在执行过程中回收。
注意点:
1. 全局变量必须在声明的时候马上初始化;
2. 命名时字母要全部大写,否则编译有警告信息;
3. 全局变量的初始化必须是编译期就能确定的常量;
4. 带有 mut 修饰的全局变量,在使用的时候必须使用 unsafe 关键字;
5. 全局变量可以写到函数外面,被任意一个函数使用。
fn main() {static G1 : i32 = 3;println!("{}, {}", G1, G1 + 20);static mut G2 : i32 = 4;unsafe {// G1 = 2; // cannot assign to immutable static item `G1`G2 = G1 + 5;println!("{}, {}", G1, G2);}
}/* 输出
3, 23
3, 8
*/
1.4 常量
常量,和变量一样都是用来存储数据的标识符,常量使用 const
关键字声明。常量的值是不可变的,不允许使用mut关键字修饰这个变量绑定。
1.4.1 常量命名
常量的命名规则和方法与静态变量基本类似,命名时字母也要全部大写。
错误示例:常量字母不全部大写可以通过编译,但有警告信息。
const pi:f32 = 3.14159; //报错
const Pi:f32 = 3.14159; //报错fn main() {println!("{}", pi);println!("{}", Pi);
}
```
warning: constant `pi` should have an upper case name
--> D:\Cpp\hello.rs:1:7
|
1 | const pi:f32 = 3.14159;
| ^^ help: convert the identifier to upper case: `PI`
|
= note: `#[warn(non_upper_case_globals)]` on by default
warning: constant `Pi` should have an upper case name
--> D:\Cpp\hello.rs:2:7
|
2 | const Pi:f32 = 3.14159;
| ^^ help: convert the identifier to upper case (notice the capitalization): `PI`
warning: 2 warnings emitted
3.14159
3.14159
```
1.4.2 常量用法
常量必须显式指定类型以及声明同时就赋值,并且常量的值必须是编译时可确定的常数或者是常量表达式。示例如下:
const PI: f64 = 3.14159;
const FLAG: bool = true;
const HOURS: u32 = 12;
const SECONDS: u32 = 60 * 60 * HOURS;
const MIN_NUM: i32 = 1 << 31;
const MAX_NUM: i32 = -(1 + MIN_NUM);fn main() {println!("{}", PI);println!("{}", FLAG);println!("{}", HOURS);println!("{}", SECONDS);println!("{}", MIN_NUM);println!("{}", MAX_NUM);
}/* 输出:
3.14159
true
12
43200
-2147483648
2147483647
*/
错误示例:常量不可以隐式赋值,或者先声明后赋值。
const PI = 3.14159; //报错
const FLAG:bool; //报错fn main() {FLAG = true; //报错println!("{}", PI);println!("{}", FLAG);
}
```
error: free constant item without body
--> D:\Cpp\hello.rs:2:1
|
2 | const FLAG:bool;
| ^^^^^^^^^^^^^^^-
| |
| help: provide a definition for the constant: `= <expr>;`
error: missing type for `const` item
--> D:\Cpp\hello.rs:1:9
|
1 | const PI = 3.14159;
| ^ help: provide a type for the constant: `: f64`
error[E0070]: invalid left-hand side of assignment
--> D:\Cpp\hello.rs:5:10
|
5 | FLAG = true;
| ---- ^
| |
| cannot assign to this expression
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0070`.
```
1.4.3 标准库常量
引用标准库中的常量,使用关键字 use 来导入。(类似 java和python 中 import)
比如std::f32或std::f64中的一些数学常量:
use std::f32::consts::PI;
use std::f32::consts::FRAC_1_PI;
use std::f32::consts::FRAC_2_PI;
use std::f32::consts::SQRT_2;
use std::f32::consts::FRAC_1_SQRT_2;
use std::f32::consts::E;
use std::f32::consts::LN_2;
use std::f32::consts::LOG2_E;
use std::f32::consts::LOG10_E;
fn main() {println!("{}", PI); println!("{}", FRAC_1_PI);println!("{}", FRAC_2_PI);println!("{}", SQRT_2);println!("{}", FRAC_1_SQRT_2);println!("{}", E);println!("{}", LN_2);println!("{}", LOG2_E);println!("{}", LOG10_E);
}/* 输出
3.1415927
0.31830987
0.63661975
1.4142135
0.70710677
2.7182817
0.6931472
1.442695
0.4342945
改std::f64,则输出
3.141592653589793
0.3183098861837907
0.6366197723675814
1.4142135623730951
0.7071067811865476
2.718281828459045
0.6931471805599453
1.4426950408889634
0.4342944819032518
*/
1.5 本章小结
1. 变量(Variables):在 Rust 中,变量默认是不可变的(immutable),也就是说,一旦被赋值后,就不能再修改其值。如果需要修改变量的值,需要使用 `mut` 关键字来声明可变变量。
2. 常量(Constants):与变量不同,常量在声明后就不能再修改其值。在 Rust 中,使用 `const` 关键字来声明常量,常量的命名规则与变量相同,但必须使用大写字母命名,并且必须在声明时就赋值。
3. 可变绑定(Mutable bindings):除了使用 `mut` 关键字来声明可变变量外,还可以使用 `let` 关键字来声明一个可变绑定。可变绑定允许我们在不改变绑定本身的情况下修改绑定所指向的值。
4. 类型推断(Type inference):Rust 支持类型推断,也就是说,可以在声明变量或常量时省略类型,由编译器自动推断类型。例如,可以使用 `let x = 42;` 来声明一个整数变量,编译器会自动推断出 x 的类型为 i32。
5. 变量遮蔽(Variable shadowing):Rust 中可以使用相同的名称来声明一个新的变量或常量,这会遮蔽之前的变量或常量。这个特性可以用来在不改变原有代码的情况下修改变量的值或类型。
6. 变量的作用域由声明的位置开始,直到当前作用域的结束;变量在离开作用域后会被自动销毁。常量在整个程序运行期间都存在。
注:本文中所有代码都可以在Rust官方线上编译器里编译通过。
Rust PlaygroundA browser interface to the Rust compiler to experiment with the languagehttps://play.rust-lang.org/?version=stable&mode=debug&edition=2021作者水平有限,如有不当之处,敬请指正。
本章完
相关文章:

Rust 快速入门60分① 看完这篇就能写代码了
Rust 一门赋予每个人构建可靠且高效软件能力的语言https://hannyang.blog.csdn.net/article/details/130467813?spm1001.2014.3001.5502关于Rust安装等内容请参考上文链接,写完上文就在考虑写点关于Rust的入门文章,本专辑将直接从Rust基础入门内容开始讲…...

【5.JS基础-JavaScript的DOM操作】
1 认识DOM和BOM 所以我们学习DOM,就是在学习如何通过JavaScript对文档进行操作的; DOM Tree的理解 DOM的学习顺序 DOM的继承关系图 2 document对象 3 节点(Node)之间的导航(navigator) 4 元素࿰…...

【大数据之Hadoop】二十九、HDFS存储优化
纠删码和异构存储测试需要5台虚拟机。准备另外一套5台服务器集群。 环境准备: (1)克隆hadoop105为hadoop106,修改ip地址和hostname,然后重启。 vim /etc/sysconfig/network-scripts/ifcfg-ens33 vim /etc/hostname r…...

SuperMap GIS基础产品组件GIS FAQ集锦(2)
SuperMap GIS基础产品组件GIS FAQ集锦(2) 【iObjects for Spark】读取GDB参数该如何填写? 【解决办法】可参考以下示例: val GDB_params new util.HashMapString, java.io.Serializable GDB_params.put(FeatureRDDProviderParam…...
C语言printf()函数中整型格式说明符详解
每个整型在printf()函数中对应不同的格式说明符,以实现该整型的打印输出。格式说明符必须使用小写。现在让我们看看各个整型及其格式说明符: 短整型(short) 10进制:%hd16进制:无负数格式,正数使用%hx8进制:无负数格式,正数使用%ho c short s 34; printf("%hd", s…...

阿里云服务器地域和可用区怎么选择合适?
阿里云服务器地域和可用区怎么选择?地域是指云服务器所在物理数据中心的位置,地域选择就近选择,访客距离地域所在城市越近网络延迟越低,速度就越快;可用区是指同一个地域下,网络和电力相互独立的区域&#…...

Java序列化引发的血案
1、引言 阿里巴巴Java开发手册在第一章节,编程规约中OOP规约的第15条提到: **【强制】**序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱&#x…...

为Linux系统添加一块新硬盘,并扩展根目录容量
我的原来ubuntu20.04系统装的时候不是LVM格式的分区, 所以先将新硬盘转成LVM,再将原来的系统dd到新硬盘,从新硬盘的分区启动,之后再将原来的分区转成LVM,在融入进来 1:将新硬盘制作成 LVM分区 我的新硬盘…...

树莓派Opencv调用摄像头(Raspberry Pi 11)
前言:本人初玩树莓派opencv,使用的是树莓派Raspberry Pi OS 11,系统若不一致请慎用,本文主要记录在树莓派上通过Opencv打开摄像头的经验。 1、系统版本 进入树莓派,打开终端输入以下代码(查看系统的版本&…...

国产ChatGPT命名图鉴
很久不见这般热闹的春天。 随着ChatGPT的威名席卷全球,大洋对岸的中国厂商也纷纷亮剑,各式本土大模型你方唱罢我登场,声势浩大的发布会排满日程表。 有趣的是,在这些大模型产品初入历史舞台之时,带给世人的第一印象其…...

操作系统——进程管理
0.关注博主有更多知识 操作系统入门知识合集 目录 0.关注博主有更多知识 4.1进程概念 4.1.1进程基本概念 思考题: 4.1.2进程状态 思考题: 4.1.3进程控制块PCB 4.2进程控制 思考题: 4.3线程 思考题: 4.4临界资源与临…...

第四十一章 Unity 输入框 (Input Field) UI
本章节我们学习输入框 (Input Field),它可以帮助我们获取用户的输入。我们点击菜单栏“GameObject”->“UI”->“Input Field”,我们调整一下它的位置,效果如下 我们在层次面板中发现,这个InputField UI元素包含两个子元素&…...

10.集合
1.泛型 1.1泛型概述 泛型的介绍 泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制 泛型的好处 把运行时期的问题提前到了编译期间避免了强制类型转换 泛型的定义格式 <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如:…...

强化学习p3-策略学习
Policy Network (策略网络) 我们无法知道策略函数 π \pi π所以要做函数近似,求一个近似的策略函数 使用策略网络 π ( a ∣ s ; θ ) \pi(a|s;\theta) π(a∣s;θ) 去近似策略函数 π ( a ∣ s ) \pi(a|s) π(a∣s) ∑ a ∈ A π ( a ∣ s ; θ ) 1 \sum_{a\in …...

初学Verilog语言基础笔记整理(实例点灯代码分析)持续更新~
实例:点灯学习 一、Verilog语法学习 1. 参考文章 刚接触Verilog,作为一个硬件小白,只能尝试着去理解,文章未完…持续更新。 参考博客文章: Verilog语言入门学习(1)Verilog语法【Verilog】一文…...

关于 std::condition_variable
一. std::condition_variable是什么? std::condition_variable 是 C 标准库提供的一个线程同步的工具,用于实现线程间的条件变量等待和通知机制。 条件变量的发生通常与某个共享变量的状态改变相关。 在多线程编程中,条件变量通常和互斥锁…...

可拓展哈希
可拓展哈希 借CMU 15445的ppt截图来说明问题。 我们传统静态hash的过程是hash函数后直接将值存入对应的bucket,但是在可扩展hash中,得查询Directory(左),存入directory指向的bucket(右)。 下面…...
Java 版 spring cloud 工程系统管理 +二次开发 工程项目管理系统源码
工程项目各模块及其功能点清单 一、系统管理 1、数据字典:实现对数据字典标签的增删改查操作 2、编码管理:实现对系统编码的增删改查操作 3、用户管理:管理和查看用户角色 4、菜单管理:实现对系统菜单的增删改查操…...
通过伴随矩阵怎么求逆矩阵
设矩阵A为n阶方阵,其伴随矩阵为Adj(A),则A的逆矩阵为: A⁻ (1/|A|) Adj(A) |A|为A的行列式 Adj(A)为A的伴随矩阵 具体步骤如下: 求出A的行列式|A| 求出A的伴随矩阵 Adj(A) 。伴随矩阵的定义为:对于A的第i行第j列…...

巡检机器人之仪表识别系统
作者主页:爱笑的男孩。 博客简介:分享机器学习、深度学习、python相关内容、日常BUG解决方法及Windows&Linux实践小技巧。 如发现文章有误,麻烦请指出,我会及时去纠正。有其他需要可以私信我或者发我邮箱:zhilong666foxmail.c…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...