文章目录
- 1. 目的
- 2. 布尔类型
- 2.1 只能赋值为小写的 true, false
- 2.2 不能把数字赋值给bool类型变量
- 2.3 正确写法汇总
 
- 3. 字符类型
- 3.1 UTF-8 编码
- 3.2 字符的意思是单个字符,多个字符不能用单引号
 
- 4. 总结
 
 
 
 
1. 目的
继续熟悉 rust 语言的基本数据类型, 感受 rust 编译期类型检查的严格, 并和 C/C++ 做简单对比。
2. 布尔类型
2.1 只能赋值为小写的 true, false
rust 语言的 bool 类型只有 true 和 false 两种取值。
换言之, 赋值为大写开头、全大写的 True, False, TRUE, FALSE, 都不被识别,编译阶段就会报错:
t1.rs:
fn main() {
    let a = true;
    let b = false;
    let c = True;
    let d = False;
    let e = TRUE;
    let f = FALSE;
    println!("a {}", a);
    println!("b {}", b);
    println!("c {}", c);
    println!("d {}", d);
    println!("e {}", e);
    println!("f {}", f);
}
(base) zz@Legion-R7000P% rustc t1.rs 
error[E0425]: cannot find value `True` in this scope
 --> t1.rs:4:13
  |
4 |     let c = True;
  |             ^^^^ not found in this scope
  |
help: you may want to use a bool value instead
  |
4 |     let c = true;
  |             ~~~~
error[E0425]: cannot find value `False` in this scope
 --> t1.rs:5:13
  |
5 |     let d = False;
  |             ^^^^^ not found in this scope
  |
help: you may want to use a bool value instead
  |
5 |     let d = false;
  |             ~~~~~
error[E0425]: cannot find value `TRUE` in this scope
 --> t1.rs:6:13
  |
6 |     let e = TRUE;
  |             ^^^^ not found in this scope
  |
help: you may want to use a bool value instead
  |
6 |     let e = true;
  |             ~~~~
error[E0425]: cannot find value `FALSE` in this scope
 --> t1.rs:7:13
  |
7 |     let f = FALSE;
  |             ^^^^^ not found in this scope
  |
help: you may want to use a bool value instead
  |
7 |     let f = false;
  |             ~~~~~
error: aborting due to 4 previous errors
2.2 不能把数字赋值给bool类型变量
t2.rs:
fn main() {
    let a:bool = 1;
    let b:bool = 0;
}
如果是来自 C/C++ 的环境, 很容易觉得奇怪,为啥不能把整数类型窄化到 bool 类型。然而 rust 就是这么的严格, 编译阶段就不让你这么写,避免潜在的坑。
看看编译报错:
(base) zz@Legion-R7000P% rustc t2.rs 
error[E0308]: mismatched types
 --> t2.rs:2:18
  |
2 |     let a:bool = 1;
  |           ----   ^ expected `bool`, found integer
  |           |
  |           expected due to this
error[E0308]: mismatched types
 --> t2.rs:3:18
  |
3 |     let b:bool = 0;
  |           ----   ^ expected `bool`, found integer
  |           |
  |           expected due to this
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
2.3 正确写法汇总
fn main() {
    let a = true;
    let b = false;
    let c:bool = true;
    let d:bool = false;
    let e:bool = a;
    let f:bool = b;
}
3. 字符类型
3.1 UTF-8 编码
rust 语言的字符使用 UTF-8 编码, 意味着既可以赋值为英文字符、数字、下划线、英文标点, 也可以用中文, 甚至 emoji。
fn main() {
    let a = 'a';
    let b = '~';
    let c = '"';
    let d = '润';
    let e = '😀';
    println!("a {}", a);
    println!("b {}", b);
    println!("c {}", c);
    println!("d {}", d);
    println!("e {}", e);
}
运行:
zz@Legion-R7000P% rustc c1.rs
zz@Legion-R7000P% ./c1 
a a
b ~
c "
d 润
e 😀
3.2 字符的意思是单个字符,多个字符不能用单引号
这一点和C/C++的概念上是一贯相承的,只不过C/C++中如果你给多个字符用单引号包起来,编译阶段并不是报错。

c2.rs:
fn main() {
    let a = '你好';
    let b = 'hi';
}
error: character literal may only contain one codepoint
 --> c2.rs:2:13
  |
2 |     let a = '你好';
  |             ^^^^^^
  |
help: if you meant to write a `str` literal, use double quotes
  |
2 |     let a = "你好";
  |             ~~~~~~
error: character literal may only contain one codepoint
 --> c2.rs:3:13
  |
3 |     let b = 'hi';
  |             ^^^^
  |
help: if you meant to write a `str` literal, use double quotes
  |
3 |     let b = "hi";
  |             ~~~~
error: aborting due to 2 previous errors
作为对比,我们用C++写一写,单引号包裹多个字符赋值到变量:
 c2.cpp
int main() {
    char a = '你好';
    char b = 'hi';
    return 0;
}
编译, 发现仅仅是报告警告:
zz@Legion-R7000P% g++ c2.cpp
c2.cpp:2:14: warning: character constant too long for its type
    2 |     char a = '你好';
      |              ^~~~~~
c2.cpp:3:14: warning: multi-character character constant [-Wmultichar]
    3 |     char b = 'hi';
      |              ^~~~
c2.cpp: In function ‘int main()’:
c2.cpp:2:14: warning: overflow in conversion from ‘int’ to ‘char’ changes value from ‘-1595562563’ to ‘'\37777777675'’ [-Woverflow]
    2 |     char a = '你好';
      |              ^~~~~~
c2.cpp:3:14: warning: overflow in conversion from ‘int’ to ‘char’ changes value from ‘26729’ to ‘'i'’ [-Woverflow]
    3 |     char b = 'hi';
      |              ^~~~
4. 总结
Rust 的数据类型, 乍一看是用 let 赋值, 似乎是和 javascript 学的, 颇有一种“自由定义类型”的感觉。
然而, 你可以指定数据类型,如 let a:bool = true, 它会“傻傻的”按你指定的类型做编译期的类型检查。
你即便不指定数据类型, 但等号右侧的值如果是瞎写, 例如 True False 这样不存在的关键字, 又或者把 >=2 个字符塞到单引号里的“胡搞行为”, rust 编译器都会一一识别并且准确报告, 相比之下 C/C++ 编译器让人觉得“很坑”: 都识别出来问题了, 就是不报告为错误。从这一点来说, rust 很安全, 习惯了“自由自在”写C/C++代码的人也许会觉得“很难受”, 而踩过“自由C/C++”代码坑的人会觉得 rust 真好。
实际上, C/C++ 把一些编译选项做人为修改, 把一些重要的 warning 强行设置为 error, 那么某种程度上就享受到了 rust 语言的那种编译期安全检查的优点, 这并不难做到, 只要使用 overlook 就可以做到:
include(overlook.cmake)
欢迎尝试。



















