首先,如 @cy2081 所说,一个 Ok 变量实际上是 Result<T, E>::Ok(T)。其中 T 代表成功状态下返回的值的类型,E 是失败时返回的错误对象的类型。之所以需要写成贴主所说的这种形式,应该是这个变量在使用处没有足够的信息能够推导出 Result<T, E> 中 E 的类型,所以需要手动加上。比如单纯一句 let r = Ok(0u32),那么编译器只能知道 r: Result<u32, ???>,而对应的 E 是无从得知的。但是平常这么写没出现什么问题,是因为有其他的条件在限制,比如(最简单的例子)一个函数是 fn f() -> Result<u32, String>,那么在里面写 { let r = Ok(0u32); r } 就是没问题的,因为编译器会从返回值类型推导出 r 的正确类型。
其次,贴主的这种情况经常出现在函数可以接受任意类型参数,而调用方需要传入 Result 作为参数的时候,由于自由度太大无法确定 Result 中模板参数的实际类型。我见过的一个例子是通过 channel 传 Result,比如 std::sync::mpsc::Sender::send,因为接受的参数类型 T 一般只需要 Send,没有其他约束,所以要传 Ok 的话必须标明 E 的类型。
至于针对 struct BBB<F,R,C>,使用 Result 的类型会是 Result<BBB<F,R,C>, E>,也就是将 BBB<F,R,C> 作为 T。如果要在一些无法推导的场合使用,会是类似这种 let bbb = BBB::new(...); let r = Ok::<_, &str>(bbb); let e = Err::<BBB<F,R,C>, _>("failed")。前者能从 bbb 得知 T 是 BBB<F,R,C>,但 E 不清楚,需要标注;后者 E 是能直接推导出来(即"failed"的类型 &str),而 T 需要手动说明。
评论区
写评论OK,感谢各位的详细解释,我想我大概明白了
首先,如 @cy2081 所说,一个
Ok
变量实际上是Result<T, E>::Ok(T)
。其中T
代表成功状态下返回的值的类型,E
是失败时返回的错误对象的类型。之所以需要写成贴主所说的这种形式,应该是这个变量在使用处没有足够的信息能够推导出Result<T, E>
中E
的类型,所以需要手动加上。比如单纯一句let r = Ok(0u32)
,那么编译器只能知道r: Result<u32, ???>
,而对应的E
是无从得知的。但是平常这么写没出现什么问题,是因为有其他的条件在限制,比如(最简单的例子)一个函数是fn f() -> Result<u32, String>
,那么在里面写{ let r = Ok(0u32); r }
就是没问题的,因为编译器会从返回值类型推导出r
的正确类型。其次,贴主的这种情况经常出现在函数可以接受任意类型参数,而调用方需要传入
Result
作为参数的时候,由于自由度太大无法确定Result
中模板参数的实际类型。我见过的一个例子是通过 channel 传Result
,比如std::sync::mpsc::Sender::send
,因为接受的参数类型T
一般只需要Send
,没有其他约束,所以要传Ok
的话必须标明E
的类型。至于针对
struct BBB<F,R,C>
,使用Result
的类型会是Result<BBB<F,R,C>, E>
,也就是将BBB<F,R,C>
作为T
。如果要在一些无法推导的场合使用,会是类似这种let bbb = BBB::new(...); let r = Ok::<_, &str>(bbb); let e = Err::<BBB<F,R,C>, _>("failed")
。前者能从bbb
得知T
是BBB<F,R,C>
,但E
不清楚,需要标注;后者E
是能直接推导出来(即"failed"的类型&str
),而T
需要手动说明。最后,
Infallible
类型是一种无法实例化的类型,也就是在说这里永远不可能出现Err
的情况。我的理解是,Ok是一种Result枚举(enum)值,其中包裹的具体值是service_fn(hello_world),下划线 _ 表示占位符,相当于泛型Result<T, E>定义中的T,表示不在乎T的具体类型是什么,Infallible相当于E,也就是有错误时的类型。对于struct BBB,一般需要先有个new函数生成实例,比如:let new_bbb = BBB::new(), 如果要在Ok中包裹new_bbb, 比如可以表示成 OK::<BBB, err>(new_bbb),err是自己指定的错误的类型。
意思是不是因为service_fn返回的是个带泛型的结构体ServiceFn<F, R>,所以要给Ok(T)指定T的类型为一个带泛型的值,所以写成Ok::<_,Infallible>(service_fn())的形式对吧,那是不是说比如我定义一个struct BBB<F,R,C>,然后需要用Ok包裹这个BBB结构的话,得写成 Ok::<F,R,C>(BBB)得形式,不知道这样理解对不对。
https://matematikaadit.github.io/posts/rust-turbofish.html
https://turbo.fish/
这个是指定泛型的时候用的。
是说返回的是个Ok(T)的值,T的类型是<_,Infallible>吗???