rust 为什么Option类型try块需要类型注解?

hs1ihplo  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(134)

编译器:rustc 1.71.0-nightly (c609da59d 2023-04-18)
#![feature(try_blocks)]的一个例子:

#![feature(try_blocks)]
fn test_try(input: Option<i32>) {
    let output = try {
        input?
    };

    println!("{:?}", output);
}

字符串
但是编译器声称output需要类型注解。完整的错误消息在这里:

error[E0282]: type annotations needed
 --> src/main.rs:3:9
  |
3 |     let output = try {
  |         ^^^^^^
  |
help: consider giving `output` an explicit type
  |
3 |     let output: /* Type */ = try {
  |               ++++++++++++


如果我尝试let output: Option<i32> = ...一切正常。
看起来output应该是Option<i32>,但编译器没有推断出这一点。
仅仅是因为功能不稳定还是我错过了什么?除了Option<i32>之外,output还可以使用其他类型吗?

8wtpewkr

8wtpewkr1#

try_blocks特性由于推理问题而大部分不稳定。Try特征(为try块和?运算符提供动力)的设计使其非常灵活,但编译器也很难推断类型。
在std中,除了Option<i32>之外,没有任何东西可以是这个表达式的结果。但是可以写一个,因为驱动try块去对称的不是其中?的类型,而是它所导致的类型。所以它可以是任何东西,只要它支持?Option<i32>。例如:

#![feature(try_blocks, try_trait_v2)]

use std::convert::Infallible;
use std::ops::ControlFlow;

#[derive(Debug)]
struct MyFancyType;

impl std::ops::FromResidual<Option<Infallible>> for MyFancyType {
    fn from_residual(_residual: Option<Infallible>) -> Self {
        Self
    }
}

impl std::ops::FromResidual for MyFancyType {
    fn from_residual(_residual: Infallible) -> Self {
        Self
    }
}

impl std::ops::Try for MyFancyType {
    type Output = i32;
    type Residual = Infallible;

    fn from_output(_output: i32) -> Self {
        Self
    }

    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
        ControlFlow::Continue(0)
    }
}

fn test_try(input: Option<i32>) {
    let output: MyFancyType = try { input? };

    println!("{:?}", output);
}

字符串
Playground的一个。

相关问题