我有以下代码段:
pub fn init(&mut self, opts: InitOptions) -> Result<(), PostalError> {
let _ = self.mutex.lock();
unsafe {
if !libpostal_setup() {
Err(PostalError::LibpostalSetup);
}
}
self.setup_done = true;
if opts.expand_address {
unsafe {
if !libpostal_setup_language_classifier() {
Err(PostalError::LibpostalEnableExpansion);
}
}
self.expand_address_enabled = true;
}
Ok(())
}
在编译时产生此错误:
error[E0282]: type annotations needed
--> src/lib.rs:110:17
|
110 | Err(PostalError::LibpostalSetup);
| ^^^ cannot infer type for `T`
我尝试了很多事情:
根据建议向Err
添加类型注释;例如Err::<(), PostalError>(PostalError::LibpostalSetup);
,可编译但产生警告和错误的运行时行为(即单个unwrap()
不再对返回的Result
起作用)。
从单位类型()
更改为u8
(用于测试)。
解决枚举变体签名的变化通常以各种方式进行,但无济于事。
很好奇的是,我有另一个具有相同类型的函数,其用法类似Result
,编译器对此没有任何麻烦:
pub fn expand_address(
&self,
a: &str,
opts: ExpandAddressOptions,
) -> Result<Expansions, PostalError> {
if self.setup_done && self.expand_address_enabled {
let _ = self.mutex.lock();
unsafe {
match CString::new(a) {
Ok(c_string) => {
let addr = c_string.as_ptr() as *mut c_char;
let mut num_expansions: usize = 0;
let raw = libpostal_expand_address(addr, opts.opts, &mut num_expansions);
Ok(Expansions::new(raw, num_expansions))
}
Err(e) => Err(PostalError::BadCString(e)),
}
}
} else {
Err(PostalError::LibpostalNotReady)
}
}
在前面的示例中,编译器到底有什么问题?
我可以(也可能)更改为Option<PostalError>
,但这使match
/ unwrap
/ ?
难以使用。如果可能的话,我宁愿不要。
答案 0 :(得分:2)
110 | Err(PostalError::LibpostalSetup);
| ^^^ cannot infer type for `T`
您错过了return
; Err(PostalError::LibpostalEnableExpansion);
是一个(无用的)语句,而不是函数的返回值,所以我猜Rust认为它无法推断您要构造的T
中的Result<T, PostalError>
。 / p>
https://doc.rust-lang.org/book/ch03-03-how-functions-work.html#function-bodies-contain-statements-and-expressions解释了如何确定函数的返回值,Are semicolons optional in Rust?解释了Rust中分号(或缺少分号)的重要性。