Почему я не могу использовать?оператор в моей основной функции на функцию, которая возвращает Option? - PullRequest
0 голосов
/ 05 декабря 2018

Используя этот файл:

use std::env;

fn main() {
    println!("{}", env::args().nth(3)?);
}

Я получаю эту ошибку:

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
 --> src/main.rs:4:20
  |
4 |     println!("{}", env::args().nth(3)?);
  |                    ^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `std::ops::Try` is not implemented for `()`
  = note: required by `std::ops::Try::from_error`

Однако это сбивает с толку, потому что nth возвращает Option:

fn nth(&mut self, n: usize) -> Option<Self::Item>

Я неправильно понимаю документацию или это ошибка?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Тип возврата main должен реализовывать std::process::Termination (в настоящее время это нестабильная черта).Если вы посмотрите на конец документации, вы увидите:

impl Termination for !
impl Termination for ()
impl Termination for ExitCode
impl<E: Debug> Termination for Result<!, E>
impl<E: Debug> Termination for Result<(), E>

Если вы хотите вернуть Option, вы должны реализовать на нем черту.Это не практично , потому что вы не можете реализовать черту для внешнего типа , поэтому лучшее решение - преобразовать Option<T> в Result<T, E>:

use std::env;

fn main() -> Result<(), Box<std::error::Error>> {
    println!("{}", env::args().nth(3).ok_or("Missing argument")?);
    Ok(())
}

См. Также:

0 голосов
/ 05 декабря 2018

Оператор ? заставит функцию, содержащую его, вернуть None, если значение, к которому применяется ?, равно None.

Это означает, что вы можете написать

fn not_main() -> Option<()> {
    println!("{}", std::env::args().nth(3)?);
    Ok(())
}

, поскольку nth возвращает Option<Item>, а not_main возвращает Option<()>.

Однако ваш main не возвращает Option, поэтому ? не может работать внутри него.

То, как вы обойдете это, будет зависеть от того, что вы хотите сделатьв случае отсутствия аргумента.Самое жестокое решение - вместо этого unwrap - что вызовет панику в вашем коде.

fn main() {
    println!("{}", env::args().nth(3).unwrap())
}

Альтернативой является сопоставление и обработка пропущенного регистра

fn main() {
    match std::env::args().nth(3) {
        Some(ref v) => println!("{}", v),
        None => println!("Missing argument"),
    }
}

, начиная с Option поддерживает Debug вы можете распечатать отладочную версию - которая выдаст None или Some("arg3").

fn main() {
    println!("{:?}", std::env::args().nth(3));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...