Result Type and File::open ->Result<File>

The Result enum defined in standard libray as follows

enum Result < T, E> {

Ok(T),
Err(E)
}

In the standard librray std::fs::File struct, the function signature of open says
it returns Result .

If the function is successful, it can return Ok( file) where file is of type File.

What happens when there is error ?.

When there is no file and hence error, will the
function returns Err(file) where file is of type struct File ?.

May please hep to understand .

Thanks,
S.Gopinath

1 Like

If the operation fails, it returns Err(err) where err has the type std::io::Error.

1 Like

File::open returns not std::result::Result, but std::io::Result. This is the specialized case where the error type is fixed and equal to std::io::Error.

In general case, Result<T, E>, as it is stated by its definition, might be either the Ok(T), i.e. "operation executed successfully with result of type T", or Err(E), i.e. "operation returned error of type E". For std::io::Error, E is fixed and T is defined by the concrete function.

4 Likes

It has become convention in Rust to define "local" type aliases called Result that incorporate the local error type, in exactly this way that std::io does it. You'll also find the same in many crates, or in other type aliases called Result in other parts of libstd.

In the docs, you can quickly see the difference by looking at the color! Type aliases are orangeish and enums are green.

See also: doc search for Result

1 Like

Thanks..

Referred the texts .. its basically

type Result = std::result::Result<T, E>

E is std::io::Error struct. consider my program here

/************************************
use std::fs::File;

fn main()
{

let fd1 = File::open("test1.txt");

let m =  match fd1 {

        Ok(file) => file,
        Err(e) => {
            println!("Hello Error");
        },


    };

println!("{:?}",m);

}

**********************/

I get compilation error. What I'm trying to do is, if I get error, I want to execute the print
statement. How to print my statement when I get error while opening the file ?

The compilation error is
--> simple3.rs:11:23
|
8 | let m = match fd1 {
| -
9 | |
10 | | Ok(file) => file,
| | ---- this is found to be of type std::fs::File
11 | | Err(e) => {
| |
_________^
12 | || println!("Hello Error");
13 | || },
| ||____^ expected struct std::fs::File, found ()
14 | |
15 | |
16 | | };
| |
- match arms have incompatible types
|
= note: expected type std::fs::File
found type ()

error: aborting due to previous error

Please use code blocks.

```
// your code here
```

For the error message too. It's unreadable as is.

And a small leading question: if there's an error, what value will be assigned to m, what do you think?

std::io::Error
??

Looking into much basics....I have a following program

enum  Message {

    Quit,
    Move { x: i32, y :i32} ,
    Write (String),
    Change (i32, i32, i32),
    Value  (i32),
}

struct Point {
     x: i32,
     y : i32,
}

 fn main()
{

    let m = Message::Move { x : 5, y :10};

    let v = Message::Value(100);

    let p = Point { x: 5, y:10};

    println!("{}",p.x);

}

I could able to "get" the value of p which of type Point.. for example
I can get x component by using p.x

Similarly I want to assign the enumerator Value(5) to an i32 type and then print that.
How to do that ?

///
//I think I put the code in code block as told by Alice.

I'm relatively new to Rust so my questions some time may be too childish or very basics.
Kindly bear with me.

Thanks,
S.Gopinath

As Rust is a strongly-typed language it won't allow you change types implicitly. You can't assign a value of Message::Value(5) to a i32-variable as it is of type Message.

What you can do is to extract values out of an enum by using match. For example:

fn main() {
    // Type annotations are not necessary but I include them for clarity.
    let v: Message = Message::Value(5);
    let x: i32 = match v { // look into 'v'
        Message::Value(inner) => inner, // If it is a 'Message::Value' return its inner value - the 'i32'
        _ => panic!(), // in every other case panic, i.e. abort, the program
    };
    println!("Value of x is: {}", x);
}

I hope this helped you.

As you pointed out these are really basic questions. I and many other people in this forum will be glad to help you if you have any further problems.

For a better understanding I strongly recommend you to give the Rust Book a try. It is online and for free. I think it is really well written and gives you a good introduction to the language and its concepts.

Thanks a lot for clarification. I have read that Rust book. Nicely written. But still subtle points
rises when I write a productive programs.

Thanks again for help being provided by the forum.

1 Like

In Rust, the enum variants can hold values and its types are specified like
a "tuple construct". For example

enum Automobile {
 
             Car(i32,String,bool),
             Motor_Cycle(i32,i32),
}

The value types , the variant or enumerator can hold is specified like a
tuple construct. For the first time, it looked like a function call (although only types are
mentioned here).

Can I say that variants holds tuple in this enum case ?. Is that abstraction is correct ?.

Thanks,
S.Gopinath

It is called a tuple variant, similar to a tuple struct:

struct Point(u32, u32);

Can I have an abstraction as tuple ?.

In this case, you'd be referring to the following:

enum Automobile {
    Car((i32, String, bool)),
    // ...etc
}

Note the double parenthesis: it means that you have tuple variant containing another tuple.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.