gpt4 book ai didi

rust - Rust 中有传统风格的 switch 语句吗?

转载 作者:行者123 更新时间:2023-11-29 08:35:50 25 4
gpt4 key购买 nike

我想将一个值与常量或其他值进行比较。在另一种语言(例如 JavaScript)中,我会这样做:

// Pretend these are values that are generated another way
let a = 23;
let b = 16;
let c = 43;
let input = 23;

switch (input) {
case a: console.log("Input is equal to a"); break;
case b: console.log("Input is equal to b"); break;
case c: console.log("Input is equal to c"); break;
default: console.log("Input does not equal any value"); break;
}

我如何在 Rust 中巧妙地做到这一点?我知道我可以用 if 语句来做到这一点,但我认为这很困惑,我正在与更多的值进行比较。

我可以使用 match 语句在 Rust 中比较变量和常量值吗?

最佳答案

进行这种案例分析的最简单方法是,当您事先知道案例的值并且不介意将它们放在代码中间时。在这种情况下,您需要一个简单的 match 表达式。

fn main() {
for &input in &[16, 23, 42, 43] {
match input {
23 => println!("Input is equal to a"),
16 => println!("Input is equal to b"),
43 => println!("Input is equal to c"),
_ => println!("Input does not equal any value"),
}
}
}

(playground link)

如果您的 a bc 是编译时常量(已知值或使用 const 函数),那么您仍然可以直接匹配它们。

const A: i32 = 23;
const B: i32 = 16;
const C: i32 = generate_c();

const fn generate_c() -> i32 {
A + B + 4
}

fn main() {
for &input in &[16, 23, 42, 43] {
match input {
A => println!("Input is equal to a"),
B => println!("Input is equal to b"),
C => println!("Input is equal to c"),
_ => println!("Input does not equal any value"),
}
}
}

(playground link)

但是,如果您尝试使用非常量变量,您会得到奇怪的输出。

fn generate_c(a: i32, b: i32) -> i32 {
a + b + 4
}

fn main() {
let a = 23;
let b = 16;
let c = generate_c(a, b);

for &input in &[16, 23, 42, 43] {
match input {
a => println!("Input is equal to a"),
b => println!("Input is equal to b"),
c => println!("Input is equal to c"),
_ => println!("Input does not equal any value"),
}
}
}

(playground link)

如果你运行这个,编译器会给你很多关于“无法到达的模式”的警告,并且输出将是“输入等于 a”所有四次。这样做的问题是匹配语句中每一行的左侧不仅仅是一个表达式,而是一个模式

模式是像 (x, [_, z], Some(_)) 这样的表达式。它由基本变量(如 xz)、下划线(_)、所有文字表达式(整数、 float 、元组、数组)和其他一些东西。

当 Rust 运行这样的匹配语句时,它会尝试在句法上将输入与模式匹配。基本变量将匹配任何内容,并且该变量的值被设置为与 match 语句的该分支范围匹配的任何内容。下划线(在上述所有示例中使用)也可以匹配任何内容,但不绑定(bind)任何变量。

在上面的 const 版本中,常量 A BC 被替换为它们各自的文字值代码中的任何地方,因此输入与这些文字值相匹配。

对于可变版本,当我们匹配a bc 时,这些字母被解释为匹配任何内容的基本变量。模式中根本不考虑变量的值。在代码中

let a = 14;
let b = 15;
let c = 16;
let input = 16;
match input {
a => println!("Input is equal to a"),
b => println!("Input is equal to b"),
c => println!("Input is equal to c"),
_ => println!("Input does not equal any value"),
}

第一个分支将始终匹配,为分支范围提供名称 a 的输入。

如果你需要匹配变量 a bc,你可以在每个分支上添加一个守卫。守卫通过添加一个分支匹配的附加条件来更多地过滤分支。在这种情况下,我们匹配任何内容并将其绑定(bind)到变量 x,然后检查 x 是否等于 a(和 bc)。

fn generate_c(a: i32, b: i32) -> i32 {
a + b + 4
}

fn main() {
let a = 23;
let b = 16;
let c = generate_c(a, b);

for &input in &[16, 23, 42, 43] {
match input {
x if x == a => println!("Input is equal to a"),
x if x == b => println!("Input is equal to b"),
x if x == c => println!("Input is equal to c"),
_ => println!("Input does not equal any value"),
}
}
}

(playground link)

这比 switch/case 结构有点冗长,但我希望它清楚发生了什么。在每个分支,变量 x 绑定(bind)到 16,然后如果它等于变量 A(或 BC),则分支被采取。否则,我们尝试下一个分支。

关于rust - Rust 中有传统风格的 switch 语句吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55804275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com