0

I'm a Rust novice and trying to read in two numbers and calculate their quotient:

use std::io;

enum Option<T> {
    None,
    Some(T),
}

fn safe_div(n: i32, d: i32) -> Option<i32> {
    if d == 0 {
        return None;
    }
    return Some(n / d);
}

fn main() {
    println!("Please input your numerator.");
    let mut numerator = String::new();
    io::stdin()
        .read_line(&mut numerator)
        .expect("Failed to read line");
    println!("Please input your denominator.");
    let mut denominator = String::new();
    io::stdin()
        .read_line(&mut denominator)
        .expect("Failed to read line");
    match safe_div(numerator, denominator) {
        None => println!("Can't divide by zero!"),
        Some(v) => println!("Quotient is {}", v),
    }
}

but I am getting the following error repeated several times when I try to compile it:

src/safe_div.rs:12:12: 12:21 error: mismatched types: expected Option<i32>, found std::option::Option<i32> (expected enum Option, found enum std::option::Option) [E0308]

What am I missing here?

ljedrz
  • 20,316
  • 4
  • 69
  • 97
wogsland
  • 9,106
  • 19
  • 57
  • 93

2 Answers2

6

By default, any Rust application includes the prelude. You can turn it off, but if you do not, it pulls in the ::std::option::Option<T> type as well as its variants None and Some into scope.

Unless someone decides to create something using those names, in which case the newly defined items take priority.

Your problem here is that you have only half-shadowed the standard Option:

  • you defined Option, which takes precedence over ::std::option::Option
  • you did NOT pull None and Some into the same scope (they are nested in the Option scope), whereas ::std::option::Option::{None, Some} are there via the prelude

The result is that Option refers to ::Option while None and Some refer to ::std::option::Option::None and ::std::option::Option::Some respectively. It's a mess.

One solution, if you really want the override, is to import None and Some yourself:

enum Option<T> {
    None,
    Some(T)
}

use Option::{None, Some};

The other is NOT to redefine Option.

Once you apply either fix, you'll realize that you are passing strings as arguments to safe_div, you can use .parse().expect("Expected i32") to parse them as integers.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • I tried this fix and the compile errors go away but it gives me the runtime error instead: `thread '
    ' panicked at 'Expected i32'` and dies rather than printing the quotient.
    – wogsland Jan 17 '17 at 18:52
0

You don't need to define Option; it's already part of the standard library. Remove the definition and it will get past that error. The next error is that you have a String that you are trying to use as a number without parsing it first.

I'd strongly recommend that you go back and read The Rust Programming Language again. The first chapters, especially the guessing game, are targeted at exactly this level of introduction.

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • @wogsland please continue reading my answer. There are only **3** sentences in the first paragraph and the *third sentence* describes that error. – Shepmaster Jan 17 '17 at 18:50
  • @wogsland As this is a site for professional programmers, I'd hope that the target audience would read the introductory documentation for a language or framework and be able to compose larger solutions out of smaller components. Besides, I **linked to an existing answer** on how to parse strings; would you prefer that an answerer write *all* of your code for you? – Shepmaster Jan 17 '17 at 19:00
  • 1
    Quick note: A site for *enthusiast* and professional programmers ;) – Matthieu M. Jan 18 '17 at 07:37