У меня есть следующий фрагмент:
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
(для тестирования).
Возиться с изменением сигнатуры варианта enum в целом различными способами, но безрезультатно.
Что любопытно, так это то, что у меня есть другая функция того же типа с аналогичным использованием 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
/ ?
неудобным для использования. Я бы предпочел нет, если это возможно.