Why i cannot use '?' after a fn which return a 'Result'?

hi,everyone,i'm newer in rust,and i saw a lot code use '?' to deal with error,and when i use ,it aways tell me :

Blockquoteerror[E0277]: the ? operator can only be used in a function that returns Result or Option (or another type that implements FromResidual)
--> src\main.rs:20:26
|
19 | / fn test_foo(){
20 | | let a :String = foo()?;
| | ^ cannot use the ? operator in a function that returns ()
21 | | }
| |_- this function should return Result or Option to accept ?
|
= help: the trait FromResidual<Result<Infallible, std::io::Error>> is not implemented for ()
note: required by from_residual

and my code is :

fn foo() -> Result<String>{
     Ok("foo".into())
}

fn test_foo(){
    let a :String = foo()?;  //this '?' compile error
}

Is anybody could tell me why? :sob: thanks!

1 Like

Don't put error messages in quote blocks; that's pretty unreadable. Put them in code blocks, too. If you don't want syntax-hightlighting, you can use "plain" for plaintext

```plain
some plain text
in code block
```

(how it's displayed:)

some plain text
in code block

To answer the question: To use ? you must not only have a value of type Result in front of the ?, but the section of code must also be inside of a function (or closure) that returns Result. Or, alternatively, you can place it after an expression that's an Option in a function/closure that's returning Option<…>.

E.g. this works

use std::io::Result;

fn foo() -> Result<String> {
    Ok("foo".into())
}

fn test_foo() -> Result<()> {
    let a: String = foo()?;
    Ok(())
}

What ? does is propagate the error. It evaluates to the contained value on success and returns the error from the containing function on failure. If your goal is not to propagate an error, in particular while prototyping code or while learning Rust, using .unwrap() can be a potentially useful alternative approach. It will panic when the Result is an Err.

4 Likes

test_foo isn't returning anything (well, technically it's returning the unit type, but let's ignore that for the sake of simplicity), and you can only use the question mark operator ? in functions that return the same type that you are short-circuiting. i.e., Result in this case:

fn foo() -> Result<String>{
     Ok("foo".into())
}

fn test_foo() -> Result<()>{
    let a :String = foo()?;  // Now this should compile
}
1 Like

thank you it works

thank you,it pass compile

than you , get it

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.