Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Rust不能推断出这种封闭性';什么是退货类型?_Rust_Type Inference - Fatal编程技术网

为什么Rust不能推断出这种封闭性';什么是退货类型?

为什么Rust不能推断出这种封闭性';什么是退货类型?,rust,type-inference,Rust,Type Inference,Rust编译器通常能够推断从闭包返回的表达式的类型: fn main() { let a_closure = |num|{ num+1.0 }; println!("{}", a_closure(1.0)); } 但当我定义相同的闭包时,编译器无法推断类型: 我很惊讶Rust不能在这里推断出它的类型:在闭包中使用return语句而不阻止编译器推断它的返回类型吗?这是因为没有分号。如果没有分号,则返回最后一个表达式,最后一个表达式是re

Rust编译器通常能够推断从闭包返回的表达式的类型:

fn main() {
    let a_closure = |num|{
        num+1.0
    };
    println!("{}", a_closure(1.0));
}
但当我定义相同的闭包时,编译器无法推断类型:


我很惊讶Rust不能在这里推断出它的类型:在闭包中使用
return
语句而不阻止编译器推断它的返回类型吗?

这是因为没有分号。如果没有分号,则返回最后一个表达式,最后一个表达式是
returnnum+1.0
。因为return语句使程序跳转到其他地方,所以它的值可以是任何值,例如:

fn main() {
    let a: String = return;
}
但是,如果编译器没有看到分配给它的直接类型,它将选择类型
()
作为返回语句的值

所以发生的事情是:

  • 编译器会看到闭包中的最后一个表达式,并默认为其指定类型
    ()
  • 然后,编译器在闭包内看到一个显式返回,返回类型
    i32

  • 因此,由于有两次尝试从闭包返回,并且它们各自返回不同的类型,这是一种类型不匹配。

    有趣的是,添加类型注释
    num:f64
    修复了使用
    return
    时的编译。缺少推理可能会作为编译器的bug或功能请求提交。然而,令人困惑的错误消息可能被认为是一个bug。消息“expected
    ()
    ,found
    f64
    ”似乎不适用于此示例,注释
    num:f64
    看起来也不应该影响它。消息适用于此错误,它说rustc将返回类型推断为
    ()
    ,但我们返回的是
    f64
    。请注意
    fn foo(){1.0f64}
    如何触发完全相同的错误消息(除了建议添加返回类型)。调用
    a_闭包(1.0f64)
    也可以解决此问题。向闭包添加显式返回类型也可以修复错误:
    num |->f64{return num+1.0}
    @masklin如果编译器的推理由要求返回类型为
    ()
    的约束支持,则错误消息是合适的,但这里的情况并非如此。这就是为什么我认为这个消息令人困惑,或者至少误导人:它似乎暗示了这样一个约束,即它不存在。此外,
    foo
    返回foo之间的差异
    (最后的分号没有区别)看起来像是一个直接的错误。这也是我的第一个猜测,但它是错误的:添加缺少的分号并不能修复错误。这无法解释为什么在代码中注释任何数字,
    return num+1.0f64
    a_closure(1.0f64)
    num:f64{…}
    将导致错误消失,以及为什么此错误似乎只在数字类型推断中出现(尝试使用特定于字符串的方法;不会出错)
    fn main() {
        let a: String = return;
    }