rust 使用“if”有条件地赋值给变量

yx2lnoni  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(91)

我有一个参数结构,然后尝试对输出进行一些基本逻辑,并在某些条件下将参数值分配给变量:

struct Args {
    name: String,
    from: String,
}

fn main() {
    let args = Args {
        name: "Jane".to_string(),
        from: "Jane Doe <jane@example.com>".to_string(),
    };
    let default_username: String = "Sendmail Wrapper".to_owned();

    let username = if args.name != default_username {
        args.name.clone();
    };
    let username = if (args.name == default_username) && (args.from != default_username) {
        args.from.clone();
    };
    println!("{}",username);
}

字符串
当运行上面的代码时,我从Rust得到错误:

error[E0277]: `()` doesn't implement `std::fmt::Display`
  --> src/main.rs:73:19
   |
73 |     println!("{}",username);
   |                   ^^^^^^^^ `()` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `()`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)


如果我使用println!("{:?}",username);println!("{:#?}",username);,我只需要打印()
如何将结构变量赋值给用户名变量?

iszxjhcz

iszxjhcz1#

您可能希望username的类型为String,但问题在于:

let username = if args.name != default_username {
    args.name.clone();
};

字符串
类似地,你有这个块,它本质上也有同样的问题:

let username = if (args.name == default_username) && (args.from != default_username) {
    args.from.clone();
};


编译器需要更确定性的东西。换句话说,您还需要具有else块。大概是这样的:

let username = if <condition> {
    args.name.clone()
} else {
    args.from.clone()
}


请注意,在该变体中,我们不仅有一个else块,它涵盖了所有可能的情况,而且块的末尾没有;
为什么不使用分号很重要?让我们用这个简单的程序来看看:

fn main() {
    let t = 5;
    let username = if t > 6 {
        "foo";
    } else {
        "bar";
    };
    username.asdf();
}


让我们来看看编译器错误:

error[E0599]: no method named `asdf` found for unit type `()` in the current scope
 --> src/main.rs:9:18
  |
9 |         username.asdf();
  |                  ^^^^ method not found in `()`


现在让我们尝试同样的事情,但不使用分号:

fn main() {
    let t = 5;
    let username = if t > 6 {
        "foo"
    } else {
        "bar"
    };
    username.asdf();
}


这次的编译器错误略有不同:

error[E0599]: no method named `asdf` found for reference `&str` in the current scope
 --> src/main.rs:9:18
  |
9 |         username.asdf();
  |                  ^^^^ method not found in `&str`


正如我们所看到的,在第二个例子中,编译器说username的类型是&str(这是我们所期望的,对吗?然而,在前面的例子中(使用分号),编译器说username的类型是()(一个零元素的元组,在Rust中类似于C,C++,Java,C#等语言中的void类型)。
这种行为的原因是我们使用if/else块作为 * 表达式 *,并且在Rust中,当块中的最后一行结尾没有;时,这实际上意味着return the_expression;
再一次,让我用一个例子来解释上面的内容。当你有这个块:

{
    foo
}


Rust将其解释为:

{
    return foo;
}


但是当你有这个块时:

{
    foo;
}


Rust将其解释为这样的内容:

{
    foo;
    return ();
}

相关问题