rak
rak

Reputation: 31

How are "Some" and "None" from "Option" accessible at any scope?

Is there some compiler built-in functionality going on, or would it be possible to implement your own enum with its variants globally accessible with rust code alone? If yes, how?

Edit: Sorry if I wasn't clear. My Question was about Some and None, not Option. For example:

enum MyOption<T> {
    MySome(T),
    MyNone,
}

impl<T> MyOption<T> {
    fn is_some(&self) -> bool {
        match self {
            Self::MySome(_) => true,
            Self::MyNone => false,
        }
    }
}

Even from "inside", I have to tell the compiler to find them in Self. So is there a way to do it like Option and have my MySome and MyNone linked to MyOption from anywhere I write them?

Upvotes: 2

Views: 639

Answers (2)

cameron1024
cameron1024

Reputation: 10196

Rust has a module called the "prelude", accessible at std::prelude, and all of its members are imported into every module by default.

If you define your own names that shadow names in the prelude, your names take precedence. This is common for types like Result, in the following pattern:

type Result<T> = std::result::Result<T, MyCustomError>;

Whenever this is in scope, it takes precedence over the Result type included from the prelude.

Note that some things in the prelude are treated in special ways by the compiler (for example Box has built-in functionality) but you can still override the name.

You can import enum variants like regular items. For example, you can write:

use MyOption::*;

fn handle_my_option(o: MyOption) {
  match o {
    MyOk(foo) => {},
    MyNone => {},
  }
}

However, you can't have these automatically imported like the ones in the prelude (you can't add anything the prelude essentially).

If you have lots of these types, you can bundle them into a file and glob import them:

// src/my_prelude.rs
pub use crate::my_option::MyOption;  // reexport the enum itself
pub use crate::my_option::MyOption::*;  // reexport the individual variants
// any other things you want everywhere

// src/foo.rs
use crate::my_prelude::*;

fn foo() -> MyOption<()> {
  if bar() {
    MySome(()),
  } else {
    MyNone
  }
}

Upvotes: 6

mcarton
mcarton

Reputation: 30061

Rust has a prelude module which is implicitly included in every file.

This module reexports commonly used things such as Option and its variants, but also types such as String, traits such as Clone, and functions such as drop.

Upvotes: 0

Related Questions