"невозможно определить тип для` T` "при использовании вариантов enum с ошибками - PullRequest
0 голосов
/ 08 июля 2019

У меня есть следующий фрагмент:

 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`

Я пробовал несколько вещей:

  1. Добавление аннотаций типов к Err, как предлагается; например Err::<(), PostalError>(PostalError::LibpostalSetup);, который компилирует, но выдает предупреждения и некорректное поведение во время выполнения (то есть один unwrap() больше не работает с возвращаемым Result).

  2. Изменение с типа устройства () на u8 (для тестирования).

  3. Возиться с изменением сигнатуры варианта 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 / ? неудобным для использования. Я бы предпочел нет, если это возможно.

1 Ответ

2 голосов
/ 09 июля 2019
 110 |             Err(PostalError::LibpostalSetup);
     |                 ^^^ cannot infer type for `T`

Вы пропустили return; Err(PostalError::LibpostalEnableExpansion); - это (бесполезный) оператор, а не возвращаемое значение функции, поэтому я предполагаю, что Rust говорит, что у него нет способа вывести T в Result<T, PostalError>, который вы пытаетесь построить.

https://doc.rust -lang.org / book / ch03-03-how-functions-work.html # функции-тела-содержат-операторы-и-выражения объясняет, как возвращаемое значение функции определяется и Являются ли точки с запятой необязательными в Rust? объясняет значение точек с запятой (или их отсутствие) в Rust.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...