129 lines
6.4 KiB
Rust
129 lines
6.4 KiB
Rust
/* 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);
|
||
|
||
} |