当前位置:网站首页>[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
structtype 、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
pubkeyword .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
EXPRIs the value of the structure type , If the named field structure is followed by..EXPR, Then any fields that do not appear will start fromEXPRGet 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..5Is the value of the structureRange {start: 3, end: 5}Abbreviation ; - expression
..Is the value of a primitive like structureRangeFullAbbreviation .
- 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
pixelsandsizePut it inGrayscaleMapValue in memory ; - Only
pixelsVectors 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
implblock : 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 .selfrepresentative :self: Queue;&selfrepresentative :self: &Queue;&mut selfrepresentative :self: &mut Queue;
Rust Must show use of
selfTo 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
selfThe ownership of the , You can getselfValue :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
splitmadeselfValue , So thatQueueTransferred outq, It can lead toqBecomes uninitialized .
correlation function (associated function): That is the method , Is associated with a particular type ;
Free functions (free function), Not as
implThe function defined by the constituent items in the block .Static methods : It also supports the definition of not
selfMethods 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
implblock , 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 ;
implMethods 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.VecIt is also a generic structure .
Type parameter : In the generic structure , In angle brackets
<>Medium “ Type name ”.Generic structure
implThe 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() } ... }SelfThe 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
newIn 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_extremaThe 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、DebugandPartialEqOther 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::cellTwo types are defined inCell<T>andRefCell<T>, You can make the target type support this capability .Cell<T>Is a containingTStructure of private value of type , There is no need to createmutquote , You can read or set the value of the private field in it .Cell::new(value): Create a newCellVariable of type , takevalueValue is transferred to .cell.get(): returncellCopy of median .cell.set(value): holdvalueValue is saved tocellin , And discard the previously saved values .setMethodicalselfParameters , In amutPass in by reference :fn set(&self, value: T) // No &mut self
RefCell<T>Is a containingTGeneric type of type .RefCell::new(value): Create a newRefCellVariable of type , takevalueValue is transferred to .ref_cell.borrow(): Return to oneRef<T>, Basically rightref_cellShared reference of median .ref_cell.borrow_mut(): Return to oneRef<T>, Basically rightref_cellModifiable references to median .
Cell<T>andRefCell<T>Characteristics :RefCellSupport borrowing itTType 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
边栏推荐
- Mall management system of database application technology course design
- LinkedList set
- Golang 时间格式整理
- C#课程设计之员工信息管理系统
- [concurrent programming] synchronization container, concurrent container, blocking queue, double ended queue and work secret
- OpenGL learning notes
- [public key cryptography] ECC elliptic cryptosystem (implementing ElGamal encryption method)
- Message queue for interprocess communication
- MySQL 8
- Student educational administration management system of C # curriculum design
猜你喜欢

C course design employee information management system

二进制转十进制,十进制转二进制

【Rust笔记】02-所有权

Vscode, idea, VIM development tool shortcut keys
![[concurrent programming] consistency hash](/img/5e/3d0a52caa8ca489a6e6267274bbb39.jpg)
[concurrent programming] consistency hash

KunlunBase MeetUP 等您来!

Mall management system of database application technology course design

Student educational administration management system of C # curriculum design

Unity interactive water ripple post-treatment

了解小程序的笔记 2022/7/3
随机推荐
Solution détaillée de toutes les formules de fonction de transfert (fonction d'activation) du réseau neuronal MATLAB
Conversion between string and int types in golang
数据库原理期末复习
Kwai 20200412 recruitment
jupyter远程服务器配置以及服务器开机自启
producer consumer problem
Why can void * be a general pointer
String class
Redis cluster series 4
UE4 source code reading_ Bone model and animation system_ Animation node
Base64编码简介
Explain sizeof, strlen, pointer, array and other combination questions in detail
Transmit pictures with Base64 encoding
Development material set
Collection interface
[redis] redis persistent RDB vs AOF (source code)
Unity Editor Extension - drag and drop
【Rust 笔记】07-结构体
MySQL containerization (1) docker installation MySQL
Go resolve ID card