为何Option类型的try块需要显式类型注解?
为什么try块需要显式类型注解?
你的问题核心在于try块的返回类型依赖Try trait,而满足约束的类型不唯一,和特性是否稳定无关。
原理拆解
try { ... }语法的返回值是任意实现了Try trait的类型,Option<i32>只是其中一种可能。哪怕你的代码里只出现了Option,编译器也无法排除其他潜在的Try实现类型——比如你完全可以自定义一个实现了Try的类型,其Output为i32,这个try块的返回值也可以是该自定义类型。
举个例子,假设我们定义这样一个类型:
#![feature(try_blocks, try_trait_v2)] use std::ops::Try; struct MyTry<T>(Option<T>); impl<T> Try for MyTry<T> { type Output = T; type Residual = Option<T>; fn from_output(output: Self::Output) -> Self { MyTry(Some(output)) } fn branch(self) -> std::ops::ControlFlow<Self::Residual, Self::Output> { match self.0 { Some(v) => std::ops::ControlFlow::Continue(v), None => std::ops::ControlFlow::Break(None), } } } fn test_try(input: Option<i32>) { // 这里output可以是MyTry<i32>,也可以是Option<i32> let output: MyTry<i32> = try { input? }; }
这段代码是完全合法的,这说明编译器确实有多个类型可选,无法仅凭input?就推断出唯一的返回类型。
和函数中?的区别
在普通函数里,?能自动推断类型是因为函数的返回类型是明确的——函数签名已经指定了返回Option<i32>,所以?会自动适配这个类型。但try块没有这样的“上下文约束”,它的返回类型是开放的,必须显式指定才能让编译器确定具体用哪个Try实现。
内容的提问来源于stack exchange,提问作者Donghyeon Lee
相关产品推荐
相关产品推荐

