Rust by Example — страница 23 из 66

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Struct visibility

Structs have an extra level of visibility with their fields. The visibility defaults to private, and can be overridden with the pub modifier. This visibility only matters when a struct is accessed from outside the module where it is defined, and has the goal of hiding information (encapsulation).

mod my {

// A public struct with a public field of generic type `T`

pub struct OpenBox {

pub contents: T,

}

// A public struct with a private field of generic type `T`

#[allow(dead_code)]

pub struct ClosedBox {

contents: T,

}

impl ClosedBox {

// A public constructor method

pub fn new(contents: T) -> ClosedBox {

ClosedBox {

contents: contents,

}

}

}

}

fn main() {

// Public structs with public fields can be constructed as usual

let open_box = my::OpenBox { contents: "public information" };

// and their fields can be normally accessed.

println!("The open box contains: {}", open_box.contents);

// Public structs with private fields cannot be constructed using field names.

// Error! `ClosedBox` has private fields

//let closed_box = my::ClosedBox { contents: "classified information" };

// TODO ^ Try uncommenting this line

// However, structs with private fields can be created using

// public constructors

let _closed_box = my::ClosedBox::new("classified information");

// and the private fields of a public struct cannot be accessed.

// Error! The `contents` field is private

//println!("The closed box contains: {}", _closed_box.contents);

// TODO ^ Try uncommenting this line

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

generics and methods

Theusedeclaration

The use declaration can be used to bind a full path to a new name, for easier access. It is often used like this:

use crate::deeply::nested::{

my_first_function,

my_second_function,

AndATraitType

};

fn main() {

my_first_function();

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

You can use the as keyword to bind imports to a different name:

// Bind the `deeply::nested::function` path to `other_function`.

use deeply::nested::function as other_function;

fn function() {

println!("called `function()`");

}

mod deeply {

pub mod nested {

pub fn function() {

println!("called `deeply::nested::function()`");

}

}

}

fn main() {

// Easier access to `deeply::nested::function`

other_function();

println!("Entering block");

{

// This is equivalent to `use deeply::nested::function as function`.

// This `function()` will shadow the outer one.

use crate::deeply::nested::function;

// `use` bindings have a local scope. In this case, the

// shadowing of `function()` is only in this block.

function();

println!("Leaving block");

}

function();

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

superandself

The super and self keywords can be used in the path to remove ambiguity when accessing items and to prevent unnecessary hardcoding of paths.

fn function() {

println!("called `function()`");

}

mod cool {

pub fn function() {

println!("called `cool::function()`");

}

}

mod my {

fn function() {

println!("called `my::function()`");

}

mod cool {

pub fn function() {

println!("called `my::cool::function()`");

}

}

pub fn indirect_call() {

// Let's access all the functions named `function` from this scope!

print!("called `my::indirect_call()`, that\n> ");

// The `self` keyword refers to the current module scope - in this case `my`.

// Calling `self::function()` and calling `function()` directly both give

// the same result, because they refer to the same function.