了解Rust的函数返回类型

时间:2019-11-29 01:40:42

标签: function rust return-type

我正在尝试通过从Rust的书中学习Rust。最常见的事情是有趣的添加。我尝试编写一些代码来适应它,因此我决定按照本章的说明进行操作,并编写一个快速的斐波那契函数,但是出现错误,我无法解决问题。任何防锈专家都会向我解释为什么会发生这种情况及其背后的逻辑。

fn fibo(x: i32) -> i32 {
    if x == 0 {
        0
    }
    else if x == 1 {
        1
    }

    fibo(x-1) + fibo(x-2)    
}

当我尝试构建此代码时,出现以下错误;

error[E0308]: mismatched types
 --> src/main.rs:6:9
  |
6 |         0
  |         ^ expected (), found integer
  |
  = note: expected type `()`
             found type `{integer}`

error[E0308]: mismatched types
 --> src/main.rs:9:9
  |
9 |         1
  |         ^ expected (), found integer
  |
  = note: expected type `()`
             found type `{integer}`

但是,如果我将代码更改为以下代码,则效果很好;

fn fibo(x: i32) -> i32 {
    if x == 0 {
        0
    }
    else if x == 1 {
        1
    }else{
        fibo(x-1) + fibo(x-2)    
    }
}

在Rust语言书中,声明了编译器检查if-else块中所有表达式的类型,但还声明如果不存在else语句,它将传递到下一行代码。既然我说过返回类型将是i32,那么编译器如何能期望错误中看到类型“()”?

2 个答案:

答案 0 :(得分:5)

这里的问题是,您尝试使用两个“ return”语句。

当一个块的最后一条语句缺少分号时,该语句的结果就是评估整个块的类型。在伪锈病中,我们可以说以下

{
    0
} -> usize

这就是说

let x = { 0 };

0设置新作用域,因为该块中没有分号,所以隐式返回该作用域,然后它成为该块的类型。因此,x: usize

那是怎么回事?
您的代码有两个隐式返回:

fn fibo(x: i32) -> i32 {
    if x == 0 { // This starts a block
        0 // First implicit return
    }
    else if x == 1 { // This also starts a block
        1 // First implicit return
    } // Therefore this entire if/else statement is an implicit return unless its output
      // is suppressed with a semicolon.

    fibo(x-1) + fibo(x-2) // Here we try to return again, which confuses rust!
} 

由于您的if/else包含隐式返回并且未分配给变量,因此就像我说以下话一样:

fn fibo(x: i32) -> i32 {
    //For the sake of explanation, let's assume x == 0
    0 // instead of your if/else

    fibo(x-1) + fibo(x-2)
}

哦,不!如何解决此问题:

fn fibo(x: i32) -> i32 {
    if x == 0 {
        // return 0; // This is an early return; this will break until it reaches the function
        0 // Since this is about implicit returns I'll use them here
    } else if x == 1 {
        1
    } else {
        fibo(x - 1) + fibo(x - 2)
    }
}

答案 1 :(得分:1)

您正试图从以()作为返回值的if-else块中返回。您可以明确指定退货,即:

fn fibo(x: i32) -> i32 {
    if x == 0 {
        return 0;
    }
    else if x == 1 {
        return 1;
    }

    fibo(x-1) + fibo(x-2)    
}

编辑:为了提高清晰度,您所做的是尝试从无法获取任何值的if-else块返回,因此如果必须返回该函数,则必须明确声明return 0;或其他内容。 编辑:在这里,由于if-else块不是函数中的最后内容,因此您的代码无效。 例如,这将完美地工作:

fn some_func(val: u8) -> u8 {
    if val == 100 {
       0
    }
    else {
        1
    }
}