Rust编程思想 ————增强的if-else条件表达式
在 Rust 中,条件语句是控制程序流程的重要组成部分。与语句相同,也是函数体的组成部分;与语句不同,条件表达式有bool值的,而语句没有。
1. 表达式和语句的区别:
- 语句(statement)是指那些执行操作但不返回值的指令;
- 表达式(expression)是指会进行计算并产生一个值作为结果的指令;
由于表达式和语句的差别,如下代码如果在 y+1 后面不跟分号,就是一个表达式(会返回 y+1 的值给 x ),如果跟了分号,就是一个语句(不会返回值给 x )。
fn main() {
let x = {
let y = 4;
y + 1
};
println!("x = {}", x);
}
2. Rust 中的条件表达式必须是 bool 类型
在C/C++中,条件表达式不一定是bool,因为编译器会自动将整型转换成bool(实际上C中都没有bool类型,只有0和1)。尤其是在C中,条件表达式可以是任何整型,只要非0就是true。为了防止写错逻辑,还制定了编码规范,比如最好不用用 if (x == 0),而是用if( !x )这种表达式,这与C语言的另一特性有关,即在C/C++中赋值表达式也可以赋值给变量,也可以作为条件表达式,所以有时手一抖容易写成if (x = 0)。在Rust中就不存在这种问题,检查更加严格,不会出现C/C++里的错误。
fn main() {
let c1 = true;
if c1 {
println!("true1");
}
//如果不是bool类型就会报错,以下代码会出现【expected `bool`, found integer】错误信息
// let c2 = 200;
// if c2 {
// println!("true2");
// }
//这个错误表明 rust 期望一个 bool 却得到了一个整数。不像 JavaScript 这样的语言,rust 并不会尝试自动地将非布尔值转换为布尔值。
//如果想要 if 代码块只在一个数字不等于 0 时执行,可以把 if 表达式修改成下面这样:
let number = 3;
if number != 0 {
println!("number is not zero");
}
}
3. 灵活的if-else
C/C++ 语言中的条件表达式用整数表示,非 0 即真,但这个规则在很多注重代码安全性的语言中是被禁止的。
在 rust 中,我们可以使用 if-else 语句来实现类似三元表达式(是一种条件表达式,它由三个操作数组成,含义是如果条件成立,则返回第一个操作数,否则返回第二个操作数)的效果。
fn main() {
let a = 100;
//三元表达式写法:
// let b = a > 10 ? 1 : -1;
//rust写法:
let b = if a > 10 { 1 } else { -1 };
println!("{}", b);
}
值得注意的是,两个函数体的类型必须一样,并且必须有一个 **else **后的代码块,否则就会报错。
fn main() {
let b = if a > 10 { 1 } else { true };
let b = if a > 10 { 1 } else { "sss" };
let b = if a > 10 { 1 } ;
//错误信息【'(', '+', '-', ';', <operator>, '[' or else expected, got '{'】
// let b = if a > 10 { 1 } { -1 };
}
个人还是非常喜欢C语言的三元运算符condition? value1: value2 ,非常简洁、漂亮,但Rust不支持,Python、Go也都不支持,当然各有原因了(参考为什么 Python、Go 和 Rust 都不支持三元运算符?)。虽然Rust中的if-else比C/C++有了增强,完全可以实现三元运算符的效果,查still觉得很麻烦,不美观。Rust应该是一个宣美的语言,不仅在性能、安全、功能等,在语法的美观上也应该是完美的,还是期望以后可以增加该特性。
if是一个表达式
因为 if 是一个表达式,我们可以在 let 语句的右侧使用它,例如
fn main() {
let condition = false;
//number 变量将会绑定到表示 if 表达式结果的值上
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
可以使用else if表达式与if和else组合来实现多重条件判断。
fn main() {
let number = 6;
if number % 4 == 0 {
println!("number by 4");
} else if number % 3 == 0 {
println!("number by 3");
} else if number % 2 == 0 {
println!("number by 2");
} else {
println!("number is not by 4, 3, or 2");
}
}
4.if-else的两个分支返回的类型必须相同(是否可以返回相同的trait?)
什么是trait?
- 在 Rust 编程语言中,trait 是一种定义类型特定行为的语言特型。trait 类似于其他语言中的接口,允许您定义类型可以实现的方法。
- trait 用于在不使用传统继承的情况下定义不同类型之间的共享行为。类型可以实现 trait,以便与实现相同 trait 的其他类型共享方法。这样做可以实现代码重用,并在 Rust 中实现多态性。
- 在 Rust 中,struct 是一种用于创建自定义数据类型的关键字。
通过 struct,您可以定义一个包含不同字段的数据结构,类似于其他编程语言中的类或对象。
fn main() {
// 定义一个名为 `Animal`(动物) 的 trait,其中包含一个名为 `make_sound`(发出声音) 的方法
trait Animal {
fn make_sound(&self);
}
struct Dog;
struct Cat;
//狗实现Animal
impl Animal for Dog {
fn make_sound(&self) {
println!("汪汪汪");
}
}
//猫实现Animal
impl Animal for Cat {
fn make_sound(&self) {
println!("喵喵喵");
}
}
//定义一个随机动物方法,根据传入的参数返回不同的动物
fn random_animal(is_dog : bool) -> Box<dyn Animal> {
if is_dog {
Box::new(Dog)
} else {
Box::new(Cat)
}
}
//传入true调用Dog,传入false调用Cat
let animal = random_animal(false);
animal.make_sound();
}
所以 if-else 的两个分支返回的类型可以返回相同的 trait