当前位置:网站首页>[rust notes] 07 structure
[rust notes] 07 structure
2022-07-03 08:35:00 【phial03】
07 - Structure
- Rust Structure , Also called structure , Equate to C/C++ Medium
struct
type 、Python Class and JavaScript Objects in the . - The structure aggregates the values of various types into one value , As a whole ( aggregate ) To deal with it .
- Rust Yes 3 Structure types .
- Named fields (named-field) Structure : Each component has a name .
- Class tuple (tuple-like) Structure : Mark the components in the order they appear .
- Primitive like element (unit-like) Structure : No components at all .
7.1 - Name the field structure
Definition of named field structure :
/// 8 Rectangle of bits of gray-scale pixels struct GrayscaleMap { pixels: Vec<u8>, size: (usize, usize) }
Naming conventions for structures :
- Hump spelling (CamelCase): The first letter of each word should be capitalized .
- Snake spelling (snake_case): The names of fields and methods should be lowercase , Underline between words .
Structure expression (struct expression): The value used to create the structure .
let width = 1024; let height = 576; let image = GrayscaleMap { pixels: vec![0; width * height], size: (width, height) };
Access the fields in the structure : Use
.
The operator .The structure is private by default , Only visible in the module that declares it . The fields in the structure are also private by default .
If you want to make the structure visible to the outside of the module , It needs to be added before its definition
pub
keyword .Public structure , Its fields can still be private .
- Other modules can use this structure and any of its public methods
- However, its private fields cannot be accessed by name
- You cannot create new structure values using structure expressions
Create values for named field structures :
- Creating a structure value requires that all fields of the structure must be visible .
- When creating a named field structure value , You can use another structure of the same type to provide omitted field values .
In the structure expression , hypothesis
EXPR
Is the value of the structure type , If the named field structure is followed by..EXPR
, Then any fields that do not appear will start fromEXPR
Get your own value in .struct Broom { name: String, height: u32, health: u32, position: (f32, f32, f32), intent: BroomIntent } // A broom (Broom) You can do it copy and clone operation #[derive(Copy, Clone)] enum BroomIntent { FetchWater, DumpWater } // Receive by value Broom, Take ownership fn chop(b: Broom) -> (Broom, Broom) { // be based on b initialization broom1, Modify only height. because String Not a replicable type . // therefore broom1 obtain b Ownership of the name let mut broom1 = Broom { height: b.height / 2, ..b }; // be based on broom1 initialization broom2. because String Not a replicable type . // So it must be cloned explicitly name let mut broom2 = Broom { name: broom1.name.clone(), ..broom1 }; // broom1 and broom2 Different nicknames broom1.name.push_str(" I"); broom2.name.push_str(" II"); (broom1, broom2) } fn main() { let hokey = Broom { name: "Hokey".to_string(), height: 60, health: 100, position: (100.0, 200.0, 0.0), intent: BroomIntent::FetchWater }; let (hokey1, hokey2) = chop(hokey); println!("{}", hokey1.name); // "Hokey I" println!("{}", hokey1.health); // 100 println!("{}", hokey2.name); // "Hokey II" println!("{}", hokey2.health); // 100 }
7.2 - Class tuple structure
Class tuple structure , Similar to tuples :
struct Bounds (usize, usize);
Create the value of class tuple structure :
let image_bounds = Bounds(1024, 768); // Bounds(1024, 768) Similar to function call // because Rust Will implicitly define a function such as : fn Bounds(elem0: usize, elem1: usize) -> Bounds { ... }
The value of a tuple like structure is called an element , Accessing these values is the same as tuples :
assert_eq!(image_bounds.0 * image_bounds.1, 786432);
Individual elements in a tuple like structure can be public , Or not .
pub struct Bounds (pub usize, pub usize);
Usage scenarios of named field structure and class tuple structure :
- Name the field structure : If you want to use it often
.
Operator to get the value of the component , It is recommended to use the named field structure . - Class tuple structure : If you want to often use pattern matching to query elements , It is recommended to use class tuple structure .
- Name the field structure : If you want to use it often
Class tuple structure is suitable for creating new types (newtype): A structure containing a component subject to strict type checking .
struct Ascii(Vec<u8>);
7.3 - Primitive like structure
A primitive like structure is a structure without any elements :
struct Onesuch;
This type has only one value , It is itself :
let o = Onesuch;
Value does not occupy memory .
Use cases :
- expression
3..5
Is the value of the structureRange {start: 3, end: 5}
Abbreviation ; - expression
..
Is the value of a primitive like structureRangeFull
Abbreviation .
- expression
7.4 - Structure layout
Rust There is no guarantee that the fields or elements of the structure will be stored in a certain order in memory .
Rust Ensure that the value of the field is directly stored in the memory block of the structure .
For the following structures :
struct GrayscaleMap { pixels: Vec<u8>, size: (usize, usize) }
- Rust Put... Directly
pixels
andsize
Put it inGrayscaleMap
Value in memory ; - Only
pixels
Vectors have their own memory blocks allocated on the heap .
- Rust Put... Directly
Use
#[repr(C)]
attribute , Compatible C/C++ The way to store structures in memory .
7.5-impl Define methods
impl
block : Define methods for structs , By a series of fn Defined correlation function ( That is the method ) Set of components ./// Implement a last in first out character queue pub struct Queue { older: Vec<char>, // Old elements , The most advanced is at the end younger: Vec<char> // The new element , The latest is at the end } impl Queue { /// Push a character to the back of the queue pub fn push(&mut self, c: char) { self.younger.push(c); } /// Take a character from the front of the queue , If possible , Take out the characters and return Some(c), /// otherwise , If the queue is empty , return None pub fn pop(&mut self) -> Option<char> { if self.older.is_empty() { if self.younger.is_empty() { return None; } // hold younger The elements in are transferred to older in , // Maintain the order of external commitments use std::mem::swap; swap(&mut self.older, &mut self.younger); self.order.reverse(); } // Come here ,older There must be elements . // Vec Of pop Method has returned Option self.older.pop() } }
self
: Passed as the first parameter , And call the value of this method on it .self
representative :self: Queue
;&self
representative :self: &Queue
;&mut self
representative :self: &mut Queue
;
Rust Must show use of
self
To refer to the value as the context when the method is called .Normal method call syntax , Will automatically implement implicit calls .
let mut q = Queue { // Structure instantiation older: Vec::new(), younger: Vec::new() }; q.push('0'); q.push('1'); assert_eq!(q.pop, Some('0')); q.push('f'); assert_eq!(q.pop(), Some('1')); assert_eq!(q.pop(), Some('f')); assert_eq!(q.pop(), None);
If the method does not need to be modified
self
, Then let it receive a shared referenceimpl Queue { pub fn is_empty(&self) -> bool { self.older.is_empyt() && self.younger.is_empty() } }
The method call expression knows which reference to borrow :
assert!(q.is_empty()); q.push('q'); assert!(!q.is_empty);
If the method is to achieve
self
The ownership of the , You can getself
Value :impl Queue { pub fn split(self) -> (Vec<char>, Vec<char>) { (self.older, self.younger) } } let mut q = Queue { older: Vec::new(), younger: Vec::new() }; q.push('P'); q.push('D'); assert_eq!(q.pop(), Some('P')); q.push('X'); let (older, younger) = q.split(); // q Become uninitialized assert_eq!(older, vec!['D']); assert_eq!(younger, vec!['X']);
If
split
madeself
Value , So thatQueue
Transferred outq
, It can lead toq
Becomes uninitialized .
correlation function (associated function): That is the method , Is associated with a particular type ;
Free functions (free function), Not as
impl
The function defined by the constituent items in the block .Static methods : It also supports the definition of not
self
Methods as parameters , Form a function associated with the structure type itself , Instead of associating values of this type . Usually used to define constructor functions .impl Queue { pub fn new() -> Queue { Queue { older: Vec::new(), younger: Vec::new() } } }
How to reference this method : Type name 、 Double colon and method name :
let mut q = Queue::new(); q.push('*'); ...
A structure type can correspond to multiple
impl
block , But these blocks must all be in the same place as defining the structure type Rust In bag .Rust Separate type definitions from method definitions , There are the following benefits :
- Easily identify the type of data members ;
- Make class primitive structure and class tuple structure more concise ;
impl
Methods can also be used to implement special types .
7.6 - Generic structs
Generic (generic) Structure : Create a template , You can insert any type in its punch .
/// For any type T,Queue<T> Contains two Vec<T> Type field pub struct Queue<T> { older: Vec<T>, younger: Vec<T> }
Queue<T>
Medium<T>
pronounce as : For any element typeT
.Vec
It is also a generic structure .
Type parameter : In the generic structure , In angle brackets
<>
Medium “ Type name ”.Generic structure
impl
The blocks are as follows :impl <T> Queue<T> { pub fn new() -> Queue<T> { Queue { older: Vec::new(), younger: Vec::new() } } pub fn push(&mut self, t: T) { self.younger.push(t); } pub fn is_empty(&self) -> bool { self.older.is_empty() && self.younger.is_empty() } ... }
Self
The type is different fromself
, Represents any type to which a method is addedpub fn new() -> Self { Queue { older: Vec::new(), younger: Vec::new() } }
In the above
new
In the method body of , There is no need to write type parameters in the construction expression , Just write itQueue {...}
.In function signature and type definition , You still need to give the type parameter .
When a static method is called , have access to Fast fish Symbol
::<>
, Provide type parameters explicitly :let mut q = Queue::<char>::new();
In development ,Rust You can automatically infer types :
let mut q = Queue::new(); let mut r = Queue::new(); q.push("CAD"); // The automatic inference is Queue<&'static str> r.push(0.74); // The automatic inference is Queue<f64>
7.7 - Structures with lifetime parameters
If the structure type contains references , Then you must specify the lifetime of these references :
struct Extrema<'elt> { greatest: &'elt i32, least: &'elt i32 }
struct Extrema<'elt>
Understood as a : Given any lifetime'elt
, Can create a containing a reference with that lifetimeExtrema<'elt>
Structure ./// Find out the maximum and minimum fn find_extrema<'s>(slice: &'s [i32]) -> Extrema<'s> { let mut greatest = &slice[0]; let mut least = &slice[0]; for i in 1..slice.len() { if slice[i] < *least { least = &slice[i]; } if slice[i] > *greatest { greatest = &slice[i]; } Extrema { greatest; least } } }
Rust Will infer the lifetime of the function call , There is no need to point out .
let a = [0, -3, 0, 15, 48]; let e = find_extrema(&a); assert_eq!(*e.least, -3); assert_eq!(*e.greatest, 48);
In development ,
find_extrema
The function signature of can be written as follows : The return type is the same as the lifetime of a parameter .fn find_extrema(slice: &[i32]) -> Extrema { ... }
7.8 - Derive common features for struct types
Type of
Copy
、Clone
、Debug
andPartialEq
Other characteristics , stay Rust It is called common or standard type (trait).The simple structure is as follows , Standard features are not supported by default :
struct Point { x: f64, y: f64 }
If you need to derive common features , You need to use
#[derive]
Attribute tags :#[derive(Copy, Clone, Debug, PartialEq)] struct Point { x: f64, y: f64 }
As long as the field type in the structure , Support some special types , Then this structure can derive such a special type .
7.9 - Internal modification ability
Internal modification ability (interior mutability): Inside a value that cannot be modified , There is a modifiable data .
std::cell
Two types are defined inCell<T>
andRefCell<T>
, You can make the target type support this capability .Cell<T>
Is a containingT
Structure of private value of type , There is no need to createmut
quote , You can read or set the value of the private field in it .Cell::new(value)
: Create a newCell
Variable of type , takevalue
Value is transferred to .cell.get()
: returncell
Copy of median .cell.set(value)
: holdvalue
Value is saved tocell
in , And discard the previously saved values .set
Methodicalself
Parameters , In amut
Pass in by reference :fn set(&self, value: T) // No &mut self
RefCell<T>
Is a containingT
Generic type of type .RefCell::new(value)
: Create a newRefCell
Variable of type , takevalue
Value is transferred to .ref_cell.borrow()
: Return to oneRef<T>
, Basically rightref_cell
Shared reference of median .ref_cell.borrow_mut()
: Return to oneRef<T>
, Basically rightref_cell
Modifiable references to median .
Cell<T>
andRefCell<T>
Characteristics :RefCell
Support borrowing itT
Type references , andCell<T>
I won't support it .- None of them are thread safe , Multiple threads are not allowed to access them at the same time .
See 《Rust Programming 》( Jim - Brandy 、 Jason, - By orendov , Translated by lisongfeng ) Chapter nine
Original address
边栏推荐
猜你喜欢
Advanced OSG collision detection
Creation of osgearth earth files to the earth ------ osgearth rendering engine series (1)
Redis data structure
Collection interface
Explain sizeof, strlen, pointer, array and other combination questions in detail
Campus lost and found platform based on SSM, source code, database script, project import and operation video tutorial, Thesis Writing Tutorial
Ue5 opencv plug-in use
Image processing 8-cnn image classification
OpenGL learning notes
Visual Studio (VS) shortcut keys
随机推荐
Jupyter remote server configuration and server startup
ArrayList
[MySQL] MySQL Performance Optimization Practice: introduction of database lock and index search principle
UE4 source code reading_ Bone model and animation system_ Animation process
LinkList
MySQL 8
How does unity fixedupdate call at a fixed frame rate
[cloud native] introduction and use of feign of microservices
Notes on understanding applets 2022/7/3
[linear table] basic operation of bidirectional linked list specify node exchange
Unity editor expansion - window, sub window, menu, right-click menu (context menu)
梯度下降法求解BP神经网络的简单Demo
Encoding and decoding of golang URL
數據庫應用技術課程設計之商城管理系統
796 · 开锁
【更新中】微信小程序学习笔记_3
Golang的range
【Rust笔记】06-包和模块
Display terrain database on osgearth ball
Osgearth north arrow display