first commit
This commit is contained in:
129
Rust_Concepts/src/borrowing.rs
Normal file
129
Rust_Concepts/src/borrowing.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
/* Rust Concepts: https://sociocyber.site/rust_concepts_v2.html
|
||||
Concept: Borrowing (shared &)
|
||||
Usage: read a value, without holding it.
|
||||
|
||||
---
|
||||
We call the action of creating a reference borrowing.
|
||||
As in real life, if a person owns something,
|
||||
you can borrow it from them. When you’re done,
|
||||
you have to give it back. You don’t own it.
|
||||
|
||||
Ampersands '&' represent references,
|
||||
and they allow you to refer to some value
|
||||
without taking ownership of it.
|
||||
|
||||
& to indicate of the parameter X is a reference.
|
||||
---
|
||||
|
||||
|
||||
Owner1 in this context means who (stack frame) hold a data in heap [MEM area]
|
||||
|
||||
Value can be shared to someone.
|
||||
& (reference) means = i want share this variable-value to someone
|
||||
|
||||
We can reference to a variable for get,read his value.
|
||||
One variable can have many who want get his value.
|
||||
|
||||
MANY readers and ONE value.
|
||||
Many & (references) to somethings.
|
||||
(many &refs allowed simultaneously)
|
||||
|
||||
We can NOT change reference.
|
||||
We can NOT change value when want to read this.
|
||||
& (reference) = not changeble, only readable
|
||||
|
||||
&owner1 means = reference to a variable for get his value.
|
||||
|
||||
STACK (and his frames) [CPU] HEAP [MEM]
|
||||
────────────────────────────────── ──────────────────────
|
||||
frame: main() ┌────────────────────┐
|
||||
┌──────────────────────────────┐ │ "Borrowing Value" │
|
||||
│ owner1 : String │ owns │ 15 bytes, UTF-8 │
|
||||
│ ┌──────────────────────────┐ │ ─────────► │ [B][o][r][r][o]... │
|
||||
│ │ ptr │ │ └────────────────────┘
|
||||
│ │ len = 15 │ │
|
||||
│ │ cap = 15 │ │
|
||||
│ └──────────────────────────┘ │
|
||||
└──────────────────────────────┘
|
||||
|
||||
frame: print_len( &owner1 )
|
||||
┌──────────────────────────────┐
|
||||
│ s : &String (borrow) │
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ ptr ──► owner1 │ │ (read-only, no copy)
|
||||
│ └──────────────────────────┘ │
|
||||
└──────────────────────────────┘
|
||||
│
|
||||
└─► borrow ends when print_len() returns
|
||||
|
||||
frame: println!("{}", owner1)
|
||||
┌──────────────────────────────┐
|
||||
│ owner1 still valid │
|
||||
│ println! auto-borrows &owner1│
|
||||
│ no & needed in code │
|
||||
└──────────────────────────────┘
|
||||
*/
|
||||
|
||||
|
||||
/* Arguments in functions creates a new stack frame
|
||||
with pointer2 --> pointer1 --> Heap first address of "v a l u e"
|
||||
|
||||
Like it: add_word(arg1: &String)
|
||||
&arg1 - new ptr -> ptr -> value
|
||||
*/
|
||||
fn print_len(string: &String) { // borrows
|
||||
println!("{}", string.len()); // Read reference (de-reference for get value) ptr2(&owner1) => get ptr1 (owner1) => read heap
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let owner1 = String::from("Borrowing Value");
|
||||
// change_value(&owner1); // Not allowed! We can't change value only READ.
|
||||
|
||||
print_len(&owner1); // borrowing, not ownership. Not change address in stack-slot for ptr (-> heap), make new ptr in stack (in new frame [ptr ──► owner1])
|
||||
// ptr2 (reference1) -> ptr1 (owner1) -> heap ["Borrowing Value"]
|
||||
// ptr2 (reference2) -> ptr1 (owner1) -> heap ["Borrowing Value"]
|
||||
// ptr2 (reference3) -> ptr1 (owner1) -> heap ["Borrowing Value"]
|
||||
// ptr2 (&owner1) -> ptr1 (owner1) -> heap ["Borrowing Value"]
|
||||
|
||||
println!("(Borrowing) {}", owner1); // not need reference. Why?
|
||||
/*
|
||||
STACK HEAP
|
||||
────────────────────────────────── ──────────────────────
|
||||
frame: main() ┌────────────────────┐
|
||||
┌──────────────────────────────┐ │ "Borrowing Value" │
|
||||
│ owner1 : String │ owns │ 15 bytes, UTF-8 │
|
||||
│ ┌──────────────────────────┐ │ ─────────► │ [B][o][r][r][o]... │
|
||||
│ │ ptr │ │ └────────────────────┘
|
||||
│ │ len = 15 │ │
|
||||
│ │ cap = 15 │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ │
|
||||
│ reference1 : &String │
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ ptr ──► owner1 (above) │ │ <── new slot in same frame
|
||||
│ └──────────────────────────┘ │
|
||||
└──────────────────────────────┘
|
||||
|
||||
frame: print_len( reference1 )
|
||||
┌──────────────────────────────┐
|
||||
│ s : &String (borrow) │
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ ptr ──► reference1 │ │ (copy of the pointer, same address)
|
||||
│ └──────────────────────────┘ │
|
||||
└──────────────────────────────┘
|
||||
│
|
||||
└─► borrow ends when print_len() returns
|
||||
reference1 still valid in main()
|
||||
owner1 still valid in main()
|
||||
|
||||
*/
|
||||
|
||||
let reference1 = &owner1; // save in new stack's slot in main frame a ptr to owner1
|
||||
// let reference2 = &owner1;
|
||||
// let reference3 = &owner1;
|
||||
|
||||
print_len(reference1);
|
||||
// print_len(reference2);
|
||||
// print_len(reference3);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user