< 返回版块

ilp64 发表于 2019-12-18 17:21

Tags:return,unit

fn r(n: i32) -> i32 {
    if n > 0 {
        0
    }
    1
}

像上面这个函数,编译会报错,如下:

  |
2 | /     if n > 0 {
3 | |         0
  | |         ^ expected `()`, found integer
4 | |     }
  | |     -- help: consider using a semicolon here
  | |_____|
  |       expected this to be `()`

看的出来编译器认为这个函数返回的是unit (),而if里面的0却是integer,所以报错了

我知道下面2种做法可以编译通过:

  1. 1放进else里面
  2. 0前面显式的加上return

现在问题来了: 这个编译不通过的函数,我标注了返回类型为i32,而且函数体内怎么看返回的也不是()啊,为什么编译器会认为返回的是()类型呢?

希望各位大佬指点一下小弟!

评论区

写评论
bluewingtan 2020-03-02 15:13

错误原因

根据《The Rust Reference》if and if let expressions中叙述

If all if and else if conditions evaluate to false then any else block is executed. An if expression evaluates to the same value as the executed block, or () if no block is evaluated. An if expression must have the same type in all situations.

则当所有ifelse if块无法匹配时,调用任何一个else块,而此代码中无else,则返回()。因此,此代码中的if表达式的else块(虽然没有显式写出)返回值为(),与if块中的i32类型不一致,报E0308错误。

解决办法

  1. 使用return语句,显式返回值。

  2. 显式写出else块。

引申

这样设计的原因主要是为了避免漏掉其它分支结构和无意扰乱执行流。

dongdong 2019-12-20 14:02

不错的问题,学习了。

作者 ilp64 2019-12-19 09:26

谢谢各位大佬👍,小弟这下清楚了

c5soft 2019-12-18 21:26

if 作为rust的表达式,要求 if 和 else 两部分类型相同,如果缺少 else 部分,else部分默认是(), 这样就要求 if 部分求值结果也是()。

javasaint 2019-12-18 17:57

我来分析一下,rust初学者,可能术语用得不太恰当,但差不多应该是这个意思

fn r(n: i32) -> i32 { if n > 0 { 0 } 1 }

rust编译器认为函数体是由一个语句和表达式组成的 if n > 0 { 0 } 和 1

因为没有else,所以它不认为if 代码块是表达式的一部份 所以做为函数返回值的是 1 这个表达式

第一个语句中的代码块的最后一行是表达式,但其它本身又不是条件赋值语句,所以编译器认为代码块应该返回的是(),也就是unit类型

1 共 5 条评论, 1 页