为什么以下代码在编译时会引发错误?
fn test(n: i32) -> Result<i32, &'static str> {
if n == 0 {
Err("error")
}
Ok(n + 1)
}
以下是错误:
error[E0308]: mismatched types
--> src/main.rs:41:9
|
41 | Err("error")
| ^^^^^^^^^^^^- help: try adding a semicolon: `;`
| |
| expected (), found enum `std::result::Result`
|
= note: expected type `()`
found type `std::result::Result<_, &str>`
以下两个版本可以毫无问题地编译。
带有else
语句:
fn test(n: i32) -> Result<i32, &'static str> {
if n == 0 {
Err("error")
}
else {
Ok(n + 1)
}
}
带有return
语句:
fn test(n: i32) -> Result<i32, &'static str> {
if n == 0 {
return Err("error");
}
Ok(n + 1)
}
我正在使用Rust 1.27.0。
答案 0 :(得分:4)
想象一下这个简化的代码:
fn test() -> i32{
{ 1 }
2
}
此操作失败,并显示以下错误:
error[E0308]: mismatched types
--> src/main.rs:2:11
|
2 | { 1 }
| ^ expected (), found integral variable
|
= note: expected type `()`
found type `{integer}`
这是因为在Rust中,完整的语句必须具有类型()
。如果要忽略值,只需添加;
即可将值转换为语句,然后将类型更改为()
并丢弃该值。
此代码编译:
fn test() -> i32{
{ 1; }
2
}
您的示例与此类似,但是if
使事情变得更加有趣。如果您写:
fn test(c: bool) -> i32{
if c { 1 }
2
}
它将失败,就像以前一样,因为第一条语句的类型不同于()
。添加;
可解决此问题:
fn test(c: bool) -> i32{
if c { 1; }
2
}
写else
也会编译,因为在函数中只有一个语句,并且其类型与函数的返回类型匹配:
fn test(c: bool) -> i32{
if c { 1 }
else { 2 }
}
请注意,两个分支必须具有相同的类型,并且两个分支中均不得包含;
。
添加return
也是可以的,因为return语句在定义上具有()
,因此其中任何一个都可以编译:
fn test1(c: bool) -> i32{
if c { return 1; }
2
}
fn test2(c: bool) -> i32{
if c { return 1 }
2
}
fn test3(c: bool) -> i32{
if c { return 1; }
else { 2 }
}
fn test4(c: bool) -> i32{
if c { return 1; }
else { return 2; }
}
请注意,在这些;
语句中,return
实际上是可选的,因为它已经是()
类型。