mirror of
https://github.com/darkicewolf50/RustBrock.git
synced 2025-06-15 04:54:17 -06:00
finished ch4
This commit is contained in:
parent
e6e5ab1a0f
commit
2e3f133c61
@ -282,3 +282,31 @@ this would cause a runtime error
|
||||
the program would output an error because it didnt get to the final line println! before exiting
|
||||
it casue the program to exit before attempting to access the invalid space
|
||||
this is a form of safe memory management that rust name
|
||||
|
||||
# Complex Data Type
|
||||
|
||||
## String Literal
|
||||
|
||||
This is a string literal it is hardcoded into a program
|
||||
Always immutable
|
||||
Fast and efficient, stored on the stack, property of being immuatable not of any real value
|
||||
```rust
|
||||
let s: &str = "hello";
|
||||
```
|
||||
|
||||
## String
|
||||
|
||||
This is a string that is stored on the heap, this can store data unkown (size, char, etc) to you at compile time
|
||||
Can be mutable, but must request space on the heap then return that memory to the heap, will be returned as soon as it is no longer valid (it calls the drop method from String)
|
||||
not as fast and efficient
|
||||
Example of a string being created form a string literal
|
||||
```rust
|
||||
let ab:String = String::from("hello");
|
||||
```
|
||||
|
||||
String concatinization example
|
||||
```rust
|
||||
let mut s = String::from("hello");
|
||||
s.push_str(", world!"); // push_str() appends a literal to a String
|
||||
println!("{s}"); // This will print `hello, world!`
|
||||
```
|
@ -1 +1 @@
|
||||
{"rustc_fingerprint":13662911779824945272,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.83.0 (90b35a623 2024-11-26)\nbinary: rustc\ncommit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf\ncommit-date: 2024-11-26\nhost: x86_64-pc-windows-msvc\nrelease: 1.83.0\nLLVM version: 19.1.1\n","stderr":""},"12744816824612481171":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Brock\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Brock\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"lahfsahf\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"pc\"\nub_checks\nwindows\n","stderr":""}},"successes":{}}
|
||||
{"rustc_fingerprint":13662911779824945272,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.83.0 (90b35a623 2024-11-26)\nbinary: rustc\ncommit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf\ncommit-date: 2024-11-26\nhost: x86_64-pc-windows-msvc\nrelease: 1.83.0\nLLVM version: 19.1.1\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Brock\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""}},"successes":{}}
|
@ -1 +1 @@
|
||||
{"rustc_fingerprint":13662911779824945272,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.83.0 (90b35a623 2024-11-26)\nbinary: rustc\ncommit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf\ncommit-date: 2024-11-26\nhost: x86_64-pc-windows-msvc\nrelease: 1.83.0\nLLVM version: 19.1.1\n","stderr":""},"12744816824612481171":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Brock\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Brock\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"lahfsahf\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"pc\"\nub_checks\nwindows\n","stderr":""}},"successes":{}}
|
||||
{"rustc_fingerprint":13662911779824945272,"outputs":{"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Brock\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.83.0 (90b35a623 2024-11-26)\nbinary: rustc\ncommit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf\ncommit-date: 2024-11-26\nhost: x86_64-pc-windows-msvc\nrelease: 1.83.0\nLLVM version: 19.1.1\n","stderr":""}},"successes":{}}
|
@ -104,6 +104,5 @@ fn looping_through_a_list_with_rev () {
|
||||
for number in (1..4).rev() {
|
||||
println!("{}!", number);
|
||||
}
|
||||
|
||||
println!("Lift-Off!!");
|
||||
}
|
||||
|
317
ownership.md
Normal file
317
ownership.md
Normal file
@ -0,0 +1,317 @@
|
||||
# Ownership
|
||||
|
||||
## Basic Rules
|
||||
1. Each value in Rust has an owner
|
||||
1. There can only be one owner at a time
|
||||
1. When owner goes out of scope, the value will be dropped
|
||||
|
||||
# Scope
|
||||
Range in which a veraible is valid, noramlly indicated by a {inside is a scope}
|
||||
|
||||
Variables are only vaid between the time they are decalred and the end of a scope
|
||||
|
||||
# Shallow Copy
|
||||
This causes a move (shallow copy) to s2 where s2 has the value previously owned by s1
|
||||
```rust
|
||||
let s1 = String::from("hello");
|
||||
// s1 is no longer the owner variable of the string, move has occured to s2
|
||||
let s2 = s1;
|
||||
// this would not work because s1 is no longer valid/has a pointer to the string
|
||||
println!("{s1}");
|
||||
```
|
||||
|
||||
|
||||
## Deep Copy
|
||||
This is a deep copy this only happens by default with primitive values
|
||||
Rust will not create a deep copy by default, therefore copies are cheap in terms of performance
|
||||
This will only copy the part on the stack, this is the same functionality as let y = x.clone()
|
||||
```rust
|
||||
let x = 5;
|
||||
let y = x;
|
||||
```
|
||||
### Deep Copy Heap
|
||||
If you want a deep copy for things on both the stack and heap then use .clone() method
|
||||
Indication that some code executing has a high performance cost
|
||||
```rust
|
||||
let s1 = String::from("hello");
|
||||
let s2 = s1.clone();
|
||||
println!("s1 = {s1}, s2 = {s2}");
|
||||
```
|
||||
|
||||
## Copy Trait
|
||||
Will not be allowed to be implemented if Drop trait has already been implemented
|
||||
trying to implement a copy trait with a drop trait will cause a complimation error
|
||||
Drop is only used when it needs something special to leave scope
|
||||
|
||||
Any group of simple scalar values implement copy
|
||||
Such as:
|
||||
- Integers like u32
|
||||
- Booleans with true/false values
|
||||
- All Float Point Values like f32, f64
|
||||
- Char
|
||||
- Tuples only if they only contain values that implement copy themselves
|
||||
-
|
||||
|
||||
## Assignment
|
||||
When you assign a completely new value to something on the heap then then the drop function qill be called on the old data on the heap automaitcally
|
||||
|
||||
```rust
|
||||
let mut s = String::from("hello");
|
||||
// drop called on the old "hello"
|
||||
s = String::from("ahoy");
|
||||
// outputs ahoy
|
||||
println!("{s}, world!");
|
||||
```
|
||||
|
||||
# Function Ownership
|
||||
This is the same as the move/shallow copy
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s = String::from("hello"); // s comes into scope
|
||||
takes_ownership(s); // s's value moves into the function...
|
||||
// ... and so is no longer valid here
|
||||
// if s was called here the s variable would no longer be valid/in scope
|
||||
let x = 5; // x comes into scope
|
||||
makes_copy(x); // x would move into the function,
|
||||
// but i32 is Copy, so it's okay to still
|
||||
// use x afterward
|
||||
// x is allowed to be used here because of low cost to copy **see deep copy heap
|
||||
} // Here, x goes out of scope, then s. But because s's value was moved, nothing
|
||||
// special happens.
|
||||
fn takes_ownership(some_string: String) { // some_string comes into scope
|
||||
println!("{some_string}");
|
||||
} // Here, some_string goes out of scope and `drop` is called. The backing
|
||||
// memory is freed.
|
||||
fn makes_copy(some_integer: i32) { // some_integer comes into scope
|
||||
println!("{some_integer}");
|
||||
} // Here, some_integer goes out of scope. Nothing special happens.
|
||||
```
|
||||
|
||||
|
||||
# Returning Multiple Values using a tuple
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s1 = String::from("hello");
|
||||
let (s2, len) = calculate_length(s1); // s1 gives up ownership to funct
|
||||
println!("The length of '{s2}' is {len}.");
|
||||
}
|
||||
fn calculate_length(s: String) -> (String, usize) {
|
||||
let length = s.len(); // len() returns the length of a String
|
||||
(s, length) // s gives up ownership to return a value
|
||||
}
|
||||
```
|
||||
|
||||
# References
|
||||
|
||||
## Rules
|
||||
1. At any given time, you can have either one mutable reference or any number of
|
||||
immutable references.
|
||||
1. References must always be valid
|
||||
|
||||
Giving access to a variable without transfering ownership/moving it
|
||||
|
||||
Can have unlimited read-only/immutable references
|
||||
|
||||
this is created by
|
||||
```rust
|
||||
let var_name: &var_to_borrow_value
|
||||
```
|
||||
|
||||
## Mutable References
|
||||
Can only have 1 mutable reference
|
||||
|
||||
this is created by
|
||||
```rust
|
||||
let var_name: &mut var_to_borrow_value
|
||||
```
|
||||
|
||||
This prevents three bad behavoirs
|
||||
- Two or more pointers access the same data at the same time.
|
||||
- At least one of the pointers is being used to write to the data.
|
||||
- There’s no mechanism being used to synchronize access to the data.
|
||||
|
||||
Also allowed
|
||||
```rust
|
||||
{
|
||||
let r1 = &mut s;
|
||||
} // r1 goes out of scope here, so we can make a new reference with no
|
||||
problems.
|
||||
let r2 = &mut s;
|
||||
```
|
||||
|
||||
## Mixing References
|
||||
NOT ALLOWED IN ONE SCOPE
|
||||
ONLY 1 Mutable Reference PER SCOPE
|
||||
OR UNLIMITED IMMUTABLE PER SCOPE
|
||||
|
||||
REFERNECE SCOPE ENDS WHEN IT IS LAST USED
|
||||
|
||||
BAD CODE EXAMPLE
|
||||
```rust
|
||||
let r1 = &s; // no problem
|
||||
let r2 = &s; // no problem
|
||||
let r3 = &mut s; // BIG PROBLEM
|
||||
```
|
||||
|
||||
OK code, not great, only possible becasue r1 and r2 are out of scope when r3 is declared
|
||||
```rust
|
||||
let mut s = String::from("hello");
|
||||
let r1 = &s; // no problem
|
||||
let r2 = &s; // no problem
|
||||
println!("{r1} and {r2}");
|
||||
// variables r1 and r2 will not be used after this point
|
||||
let r3 = &mut s; // no problem
|
||||
println!("{r3}");
|
||||
```
|
||||
|
||||
## Dangling Reference
|
||||
Compiler will guarantee that this cannot happen
|
||||
This happens when a pointer refers to an address in memory that was freed by another variable and possibly used by something else
|
||||
|
||||
```rust
|
||||
fn dangle() -> &String { // dangle returns a reference to a String
|
||||
let s = String::from("hello"); // s is a new String
|
||||
&s // we return a reference to the String, s
|
||||
} // Here, s goes out of scope, and is dropped. Its memory goes away.
|
||||
// Danger!
|
||||
```
|
||||
|
||||
Fixed Code
|
||||
|
||||
```rust
|
||||
fn dangle() -> String { // dangle returns a String
|
||||
let s = String::from("hello"); // s is a new String
|
||||
|
||||
s
|
||||
} // Here, s goes out of scope, and ownership is transfered and nothing other than the s namespcae is deallocated
|
||||
```
|
||||
|
||||
|
||||
## Slices
|
||||
Let you reference a continuous sequence of elements
|
||||
The sequence does not have an owner is reference only
|
||||
it is considered a slice which is a kind of reference
|
||||
|
||||
example use
|
||||
want to find the first word in a string words are seperated by a space
|
||||
|
||||
This has a problem the usize only makes sense for the reference to thee string as it currently is, if the value the string was references changes than usize makes no sense/is not connected to the state of the string/out of sync
|
||||
```rust
|
||||
// dont want ownership so reference is fine, returns usize this is the index of the space
|
||||
fn first_word(s: &String) -> usize {
|
||||
// convert string to an array of bytes so that we can go through it
|
||||
let bytes = s.as_bytes();
|
||||
// create iterator for bytes, method that returns each element in an array
|
||||
// enumerate, returns it as a part of a tuple instead which is destructed
|
||||
// i is the index and titem is the iteam itself to compair in the if statement
|
||||
// need to be a reference to that ownership doesnt change
|
||||
for (i, &item) in bytes.iter().enumerate() {
|
||||
if item == b' ' {
|
||||
// index of the space
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// if there are no spaces in the string then return the whole length
|
||||
s.len()
|
||||
}
|
||||
```
|
||||
|
||||
### String Slices
|
||||
Slices must occur at the utf-8 character boundaries, slices at the character within a charcter's boundaries will cause an error
|
||||
This is constructed by
|
||||
```rust
|
||||
let var_name = &string_to_refer[start_index..end_index]
|
||||
```
|
||||
|
||||
.. is range syntx in rust
|
||||
|
||||
```rust
|
||||
let a = [..2]; // range starts at 0 and goes to 2
|
||||
let b = [0..2]; // the same as a in terms of range
|
||||
|
||||
let c = [3..len]; // goes from 3 to the end
|
||||
let d = [3..]; // the same as c in terms of range
|
||||
|
||||
let f = &s[..]; // the whole range of s, where s is some string
|
||||
```
|
||||
|
||||
|
||||
Example
|
||||
```rust
|
||||
let s = String::from("hello world");
|
||||
let hello = &s[0..5]; // hello
|
||||
let world = &s[6..11]; // world
|
||||
```
|
||||
|
||||
Revised Example with String Slice
|
||||
The value returned by this function is guaranteed to be related to the vairable passed in
|
||||
If it is not valid the complier will catch it and throw out a borrowing rule error (two reference types mixing)
|
||||
```rust
|
||||
fn first_word(s: &String) -> &str {
|
||||
let bytes = s.as_bytes();
|
||||
for (i, &item) in bytes.iter().enumerate() {
|
||||
if item == b' ' {
|
||||
return &s[0..i];
|
||||
}
|
||||
}
|
||||
&s[..]
|
||||
}
|
||||
```
|
||||
|
||||
### String Literal Slices
|
||||
```rust
|
||||
let s: &str = "hello World"
|
||||
```
|
||||
|
||||
This is the same type as a string slice bbut it is a special kind that points to a specific part of the binary
|
||||
|
||||
### String Slices as a parameter
|
||||
to improve the function you can change the reference form &String to &str to also handle string literals without sacrifices to the base functionality
|
||||
this takes advantage of deref coercions
|
||||
```rust
|
||||
fn first_word(s: &str) -> &str
|
||||
```
|
||||
|
||||
|
||||
### Example Perfected
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let my_string = String::from("hello world");
|
||||
// `first_word` works on slices of `String`s, whether partial or whole
|
||||
let word = first_word(&my_string[0..6]);
|
||||
let word = first_word(&my_string[..]);
|
||||
// `first_word` also works on references to `String`s, which are equivalent
|
||||
// to whole slices of `String`s
|
||||
let word = first_word(&my_string);
|
||||
let my_string_literal = "hello world";
|
||||
// `first_word` works on slices of string literals, whether partial or whole
|
||||
let word = first_word(&my_string_literal[0..6]);
|
||||
let word = first_word(&my_string_literal[..]);
|
||||
// Because string literals *are* string slices already,
|
||||
// this works too, without the slice syntax!
|
||||
let word = first_word(my_string_literal);
|
||||
}
|
||||
|
||||
fn first_word(s: &str) -> &str {
|
||||
let bytes = s.as_bytes();
|
||||
for (i, &item) in bytes.iter().enumerate() {
|
||||
if item == b' ' {
|
||||
return &s[0..i];
|
||||
}
|
||||
}
|
||||
&s[..]
|
||||
}
|
||||
```
|
||||
|
||||
### Other Slices
|
||||
This is a more general use of a slice
|
||||
```rust
|
||||
let a = [1, 2, 3, 4, 5];
|
||||
let slice = &a[1..3];
|
||||
assert_eq!(slice, &[2, 3]);
|
||||
```
|
||||
|
||||
This has a slice type of &[i32]
|
7
ownership/Cargo.lock
generated
Normal file
7
ownership/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ownership"
|
||||
version = "0.1.0"
|
6
ownership/Cargo.toml
Normal file
6
ownership/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "ownership"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
34
ownership/src/main.rs
Normal file
34
ownership/src/main.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use std::char;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
// ownership_ex();
|
||||
borrowing_references();
|
||||
}
|
||||
|
||||
|
||||
fn ownership_transfer_ex () {
|
||||
// this is a string literal
|
||||
let s = "hello";
|
||||
// this is a string
|
||||
let ab = String::from("hello");
|
||||
let a: char = ab.chars().nth(0).expect("REASON");
|
||||
println!("{}", a); // outputs 'h'
|
||||
|
||||
// do stuff with s
|
||||
}
|
||||
// is is out of scope and therefore invalid
|
||||
|
||||
fn borrowing_references () {
|
||||
let mut s1 = String::from("hello");
|
||||
change_string(&mut s1);
|
||||
// s1 is still valid aat this point so ownership didint change
|
||||
println!("{}", s1);
|
||||
// do more stuff with s1
|
||||
}
|
||||
|
||||
fn change_string (some_string: &mut String) {
|
||||
// using borrowed value contained in some_string
|
||||
some_string.push_str(", world");
|
||||
// some_string out of scope and therefore invalid
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user