使用错误枚举变体时“无法推断‘T’的类型”

pat*_*ckn 1 rust

我有以下片段:

 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(())
}
Run Code Online (Sandbox Code Playgroud)

编译时会产生此错误:

 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(())
}
Run Code Online (Sandbox Code Playgroud)

我尝试了很多事情:

  1. Err按照建议向 中添加类型注释;例如Err::<(), PostalError>(PostalError::LibpostalSetup);,它编译但产生警告和不正确的运行时行为(即单个unwrap()不再适用于返回的Result)。

  2. 从单元类型更改()u8(用于测试)。

  3. 摆弄枚举变体签名通常以各种方式更改,但无济于事。

奇怪的是,我有另一个相同类型的函数,具有类似的用法,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)
    }
}
Run Code Online (Sandbox Code Playgroud)

在前一个示例中,编译器到底有什么问题?

我可以(也许)变化Option<PostalError>,但使match/ unwrap/?难以使用。如果可能的话,我宁愿不这样做。

Nic*_*lay 6

 110 |             Err(PostalError::LibpostalSetup);
     |                 ^^^ cannot infer type for `T`
Run Code Online (Sandbox Code Playgroud)

你错过了一个 return.

Err(PostalError::LibpostalSetup); 是一个无用的语句,而不是函数的返回值,所以我猜 Rust 是说它无法推断 TResult<T, PostalError>你试图构建。

函数体包含语句和表达式”解释了函数的返回值是如何确定的,“分号在 Rust 中是可选的吗? ”解释了分号在 Rust 中的重要性,或者没有分号。