嵌入式工程师不熟悉的 Rust 符号
介绍
大家好,我是@yagisawa,一位传统的嵌入式工程师。
在学习 Rust 时,我有时会遇到在 C 中看不到的语言规范(主要是如何使用符号),因此我以类似备忘单的方式对其进行了总结。
随着我们了解更多,我们将继续更新。
"XXX
在锈等等我使用它”,但请注意,除了我在本文中介绍的方法之外,可能还有其他方法可以使用它,只是因为我没有足够的研究。
请注意,可能有我不知道的 C 用法。由于工作关系,我主要处理C89的规格。此外,由于本文的主要关注点是 Rust,C 信息的丰富性并不重要。
Rust 和 C 符号列表基于以下文章。
象征
!
在 C 中,它用于 論理否定
非等価比較
等。
C。
// 論理否定
flg = !flg;
// 非等価演算
if ( flg != false ) { ... }
在 Rust 中,它用于 マクロ展開
和 論理否定
非等価比較
。
宏扩展
Rust 宏非常困难,所以让我们举一个 C 用户可能熟悉的例子。
锈
macro_rules! abs {
($e: expr) => (if $e < 0 {-$e} else {$e})
}
fn main() {
let ret = abs!(-2);
println!("{}", ret);
}
我制作了一个熟悉的 (?) 宏,名为 abs
。写abs!
来展开宏。
您可能已经注意到,Rust 是一个标准的输出处理宏。
如果您想了解更多关于宏的信息,请参阅下面的文章(或者更确切地说,我也会研究这个……)。
:
在 C 中,它用于 三項演算子
ラベル
等。
C。
// 三項演算子
max = (val1 > val2) ? val1 : val2;
// ラベル
switch ( operator ) {
case ADD: result = val1 + val2; break;
case SUB: result = val1 - val2; break;
case MUL: result = val1 * val2; break;
case DIV: result = val1 / val2; break;
}
Rust 使用ラベル
、型制約
構造体フィールド初期化子
等。
另外,Rust 的ラベル
仅限于ループラベル
,你不能使用goto
在C 中随意跳转。细节是循环标签将进行描述。
顺便说一句,Rust 没有三元运算符。
类型约束
声明变量时使用了一个易于理解的示例。
锈
fn main() {
let x: u32 = 1024;
println!("{}", x);
}
顺便说一句,Rust 有类型推断,所以
锈
fn print_type_of<T>(_: T) {
println!("{}", std::any::type_name::<T>())
}
fn main() {
let x = 1024;
print_type_of(x);
}
您可以声明一个变量而无需编写类似的类型(在我的执行环境中它是i32
)
顺便说一句,Rust 很聪明,
锈
fn main() {
let x: u8 = 1024;
println!("{}", x);
}
如果你这样做
error: literal out of range for `u8`
--> Main.rs:2:17
|
2 | let x: u8 = 1024;
| ^^^^
|
= note: `#[deny(overflowing_literals)]` on by default
= note: the literal `1024` does not fit into the type `u8` whose range is `0..=255`
error: aborting due to previous error
将导致错误。
结构字段初始化器
锈
struct Point {
x: i32,
y: i32
}
fn main() {
let origin = Point {x: 0, y: 0};
println!("x = {}, y = {}", origin.x, origin.y);
}
当初始化一个名为origin
的Point
类型变量时,这样写。
;
在 C 语言中,我认为它只在句子中的 終端子
周围使用,但在 Rust 中,它在 終端子
和 固定長配列記法
的一部分中使用。
固定长度数组表示法
锈
fn main() {
let a1: [i32; 5] = [1, 2, 3, 4, 5];
println!("{:?}", a1);
let a2 = [100; 5];
println!("{:?}", a2);
}
在声明和初始化固定长度数组时这样写。
a1
是类型约束指定数组类型和大小。
a2
将所有元素初始化为 100。您没有指定a2
的类型,但类型和大小是从右值推断出来的。
'
在 C 中,我认为它只在文字
周围使用。
C。
char c = 'a';
Rust 使用文字
、ループラベル
名前付きのライフタイム
等。
循环标签
在 Rust 中,你可以编写诸如 for
while
loop
之类的循环,但在其中
锈
fn main() {
let mut tbl = [[0; 3]; 3];
tbl[1][2] = 10;
'escape_label: for ary in tbl {
for val in ary {
println!("search!");
if val != 0 { break 'escape_label; }
}
}
println!("{:?}", tbl);
}
可以标记为通过使用break
指定标签,您可以一次退出多个循环。方便的。
寿命
我认为这是一个C用户不太了解的概念,所以让我们从一个C示例开始。
C。
#include <stdio.h>
int *max( int *val1, int *val2 ) {
return (*val1 > *val2) ? val1 : val2;
}
int main( void ) {
int x = 1;
int *result;
{
int y = 10;
result = max(&x, &y);
}
printf("%d\n", *result);
}
C 可以正常编译和运行这个程序。
输出结果正好是正确的,但是在max
内(因为y的值更大),返回了y
的指针并赋值给result
,所以当printf
是result
时应该是out了的范围。尝试printf("%d %d\n", *result, y);
将导致错误。
如果你在 Rust 中做类似的事情,
锈
fn max( val1: &i32, val2: &i32 ) -> &i32 {
return if *val1 > *val2 { val1 } else { val2 };
}
fn main() {
let x = 1;
let result;
{
let y = 10;
result = max(&x, &y);
}
println!("{}", result);
}
error[E0106]: missing lifetime specifier
--> Main.rs:1:37
|
1 | fn max( val1: &i32, val2: &i32 ) -> &i32 {
| ---- ---- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `val1` or `val2`
help: consider introducing a named lifetime parameter
|
1 | fn max<'a>( val1: &'a i32, val2: &'a i32 ) -> &'a i32 {
| ++++ ++ ++ ++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0106`.
出现“缺少生命周期说明符”的错误。
如果我像示例中一样添加生命周期参数
锈
fn max<'a>( val1: &'a i32, val2: &'a i32 ) -> &'a i32 {
return if *val1 > *val2 { val1 } else { val2 };
}
fn main() {
let x = 1;
let result;
{
let y = 10;
result = max(&x, &y);
}
println!("{}", result);
}
error[E0597]: `y` does not live long enough
--> Main.rs:11:26
|
11 | result = max(&x, &y);
| ^^ borrowed value does not live long enough
12 | }
| - `y` dropped here while still borrowed
13 |
14 | println!("{}", result);
| ------ borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
这次它变成了一个错误“`y` can not live long”。
我将'a
添加到所有参数和返回值,意思是“所有参数和返回值具有相同的生命周期'a
”。因此,两个参数中较短者的生命周期(本例中为 y
的生命周期)也应用于返回值,从而导致错误。
作为补充,我认为在互联网上的示例中,'a
'b
'static
是终身使用的。 'static
具有“只要程序运行就有效的值的引用”的特殊含义,即最长生命周期,但除此之外任何名称似乎都可以。
简而言之
锈
fn max<'shortest_lifetime>( val1: &'shortest_lifetime i32, val2: &'shortest_lifetime i32 ) -> &'shortest_lifetime i32 {
return if *val1 > *val2 { val1 } else { val2 };
}
这可以。
正如预期的那样关键词没用,但'i32
很好。
_
在 C 语言中,它可能仅在以蛇形情况编写变量、函数名等时使用。
C。
int some_val = 123;
除了 変数・関数名
等之外,Rust 还使用 「無視」パターン束縛
整数リテラル
等。
“忽略”模式绑定
有很多图案
锈
fn main() {
let x = 10;
match x {
0 => println!("x is 0."),
1 => println!("x is 1."),
_ => println!("x is other.")
}
}
最初用于match式
。这就像switch文
的default
。
fn foo(_: i32) {
println!("繰り返すだけ");
}
fn main() {
let x = [1, 2, 3, 4, 5];
for _ in x {
foo(0);
}
}
然后你也可以像这样忽略整个 for 或参数值:
锈
fn main() {
let x = 10;
let warn = 20;
let _not_warn = 30;
println!("{}", x);
}
Rust 会对未使用的变量发出警告,但如果您在变量名前加上 _
,即使该变量未使用,您也不会收到警告。
整数字面量
锈
fn main() {
let a = 1_000_000;
let b: u32 = 0x8000_FFFA;
println!("{}, {:X}", a, b);
}
整数文字可以用_
分隔以提高可读性。
@
待定更多
|
待定更多
?
待定更多
#
待定更多
$
待定更多
()
待定更多
<>
待定更多
..
待定更多
->
待定更多
=>
待定更多
...
待定更多
综上所述
学习任何新语言时,不熟悉的符号可能会令人困惑。在搜索中很难找到符号,我什至不知道它们的名字。
我希望这篇文章可以作为 Rust 新手的指南……或者说它至少可以作为你搜索的触发器可能有点夸张。
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308626064.html