【问题标题】:Difference between statement and expressions语句和表达式之间的区别
【发布时间】:2021-08-15 18:25:26
【问题描述】:

我了解 Rust 中表达式和语句的概念,但是《The Rust Programming Language》一书中的一段代码让我很困惑。

代码如下:

fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    println!("The result is {}", result);
}

result 被分配了一个表达式(否则代码将无法工作)但counter * 2 之后的分号让我认为这是一个语句。

作者在别处写道

表达式不包括结束分号。如果添加分号 到表达式的结尾,你把它变成一个语句,这将 然后不返回值

有人可以帮我澄清一下吗?

【问题讨论】:

  • break X 后面的分号不会改变loop 表达式的类型,因为循环被定义为将类型传递给break,即X 的类型。 (return X 之后的分号也是如此。)
  • loopbreak 很特别,如果你不明白,你可能不需要担心这个。

标签: rust


【解决方案1】:

Rust 是一种面向表达式的语言。这意味着包括控制流构造在内的大多数构造都是表达式。后跟分号; 的表达式是一个语句,其作用是对表达式求值并丢弃其结果。因此,表达式和语句之间的区别不太重要。 然而,如果你来自其他语言,有些表达会出现分歧,有点奇怪。

break counter * 2 是一个表达式。这个表达式的类型和值是什么?这是一个不同的表达。它没有值,类型是没有值的类型!。想象写作:

let foo = break counter * 2;

foo的类型是什么。不能有break 的效果,它本质上是一个goto,同时还返回一个值并继续循环。因此,break 表达式的类型始终是没有值的类型。一个无人居住的类型,一个没有任何值的类型,可能看起来很奇怪,但从概念上来说它很好。它是永远不会返回的函数的返回类型。这是无限循环的类型,永远无法计算出一个值。

是的,break counter * 2; 是丢弃表达式 break counter * 2 的值的语句,但表达式的值不是 counter * 2

loop { ... } 的类型是什么?通过法令,it is the type of the expressions 在循环中的任何 break 表达式中。 loop 的值必须来自 break 表达式之一。

所以,如果你添加一些类型:

fn main() {
    // The type of counter is i32, because it is not
    // suffixed with a different literal type, and no
    // use below causes a different type to be inferred.
    let mut counter: i32 = 0;

    // The type of result is the type of the loop
    // expression, which by definition is the type of
    // the expressions passed to `break` within the
    // loop. There is only one `break`, which is passed
    // counter * 2, of type i32.
    let result: i32 = loop {
        counter += 1;

        if counter == 10 {
            // The type of this expression is !.
            // Since a semicolon follows, the value
            // is discarded, but the expression has no value.
            break counter * 2;
        }
    };

    println!("The result is {}", result);
}

【讨论】:

    猜你喜欢
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 2012-06-01
    • 2013-09-18
    • 1970-01-01
    相关资源
    最近更新 更多