Присвояване, копиране, референции

11 октомври 2022

Административни неща

Административни неща

Административни неща

Административни неща

Въпрос 1

Намерете грешката

1 2 3 4 5 6
let x = 3;
let y = 5_i32;

x = x + y;

println!("{}", x);

Въпрос 1

Намерете грешката

1 2 3 4 5 6
let x = 3;
let y = 5_i32;

x = x + y;

println!("{}", x);
error[E0384]: cannot assign twice to immutable variable `x` --> src/bin/main_793bd1e82f6a5e8e900d20244b579b139e851656.rs:6:1 | 3 | let x = 3; | - | | | first assignment to `x` | help: consider making this binding mutable: `mut x` ... 6 | x = x + y; | ^^^^^^^^^ cannot assign twice to immutable variable For more information about this error, try `rustc --explain E0384`. error: could not compile `rust` due to previous error
fn main() {
let x = 3;
let y = 5_i32;

x = x + y;

println!("{}", x);
}

Въпрос 1

Как може да я оправим?

1 2 3 4 5 6
let x = 3;
let y = 5_i32;

let x = x + y;

println!("{}", x);
8
fn main() {
let x = 3;
let y = 5_i32;

let x = x + y;

println!("{}", x);
}

Въпрос 2

Намерете грешката

1 2 3 4 5 6
let x = 3.14_f32 as u32;
let y = 5_i32;

let z = x + y;

println!("{}", z);

Въпрос 2

Намерете грешката

1 2 3 4 5 6
let x = 3.14_f32 as u32;
let y = 5_i32;

let z = x + y;

println!("{}", z);
error[E0308]: mismatched types --> src/bin/main_2e0ed2c7322a9afaac10ab153c9b25e128a54dd9.rs:6:13 | 6 | let z = x + y; | ^ expected `u32`, found `i32` error[E0277]: cannot add `i32` to `u32` --> src/bin/main_2e0ed2c7322a9afaac10ab153c9b25e128a54dd9.rs:6:11 | 6 | let z = x + y; | ^ no implementation for `u32 + i32` | = help: the trait `Add<i32>` is not implemented for `u32` = help: the following other types implement trait `Add<Rhs>`: <&'a f32 as Add<f32>> <&'a f64 as Add<f64>> <&'a i128 as Add<i128>> <&'a i16 as Add<i16>> <&'a i32 as Add<i32>> <&'a i64 as Add<i64>> <&'a i8 as Add<i8>> <&'a isize as Add<isize>> and 48 others Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. error: could not compile `rust` due to 2 previous errors
fn main() {
let x = 3.14_f32 as u32;
let y = 5_i32;

let z = x + y;

println!("{}", z);
}

Въпрос 2

Как може да я оправим?

1 2 3 4 5 6
let x = 3.14_f32 as u32;
let y = 5_i32;

let z = (x as u8) + (y as u8);

println!("{}", z);
8
fn main() {
let x = 3.14_f32 as u32;
let y = 5_i32;

let z = (x as u8) + (y as u8);

println!("{}", z);
}

Преговор

Преговор

Преговор

Преговор

Преговор

Преговор

Преговор

Преговор

Присвояване

Числа

1 2
let a = 7;
let b = a;
fn main() {
let a = 7;
let b = a;
}

Присвояване

Числа

1 2 3 4
let a = 7;
let b = a;

println!("a = {}, b = {}", a, b);
a = 7, b = 7
fn main() {
let a = 7;
let b = a;

println!("a = {}, b = {}", a, b);
}

Присвояване

Статични низове

1 2
let a = "Hello";
let b = a;
fn main() {
let a = "Hello";
let b = a;
}

Присвояване

Статични низове

1 2 3 4 5
let a = "Hello";
let b = a;

println!("{}!", a);
println!("{} again!", b);
Hello! Hello again!
fn main() {
let a = "Hello";
let b = a;

println!("{}!", a);
println!("{} again!", b);
}

Присвояване

Динамични низове

1 2
let s1 = String::from("Cookies!");
let s2 = s1;
fn main() {
let s1 = String::from("Cookies!");
let s2 = s1;
}

Присвояване

Динамични низове

1 2 3 4 5
let s1 = String::from("Cookies!");
let s2 = s1;

println!("{}", s1);
println!("Mmm, {}", s2);

Присвояване

Динамични низове

1 2 3 4 5
let s1 = String::from("Cookies!");
let s2 = s1;

println!("{}", s1);
println!("Mmm, {}", s2);
error[E0382]: borrow of moved value: `s1` --> src/bin/main_9bd3356d7798f6992589bc25a22e3d30f92002bb.rs:5:16 | 2 | let s1 = String::from("Cookies!"); | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here 4 | 5 | println!("{}", s1); | ^^ value borrowed here after move | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0382`. error: could not compile `rust` due to previous error
fn main() {
let s1 = String::from("Cookies!");
let s2 = s1;

println!("{}", s1);
println!("Mmm, {}", s2);
}

Присвояване

Разполагане в паметта

Разполагане в паметта

String - динамичен низ

Разполагане в паметта

s2 = s1

Вариант: побитово копиране на стека → двойна деалокация

Разполагане в паметта

s2 = s1

Вариант: копие на стека и на динамичната памет - може да доведе до забавяне

Семантика на местене (Move semantics)

Вместо копиране, което е скъпо в някои случаи, Rust използва местене

1 2 3 4 5
let s1 = String::from("Cookies!");
let s2 = s1;

println!("{}", s1);
println!("Mmm, {}", s2);
error[E0382]: borrow of moved value: `s1` --> src/bin/main_9bd3356d7798f6992589bc25a22e3d30f92002bb.rs:5:16 | 2 | let s1 = String::from("Cookies!"); | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here 4 | 5 | println!("{}", s1); | ^^ value borrowed here after move | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0382`. error: could not compile `rust` due to previous error
fn main() {
let s1 = String::from("Cookies!");
let s2 = s1;

println!("{}", s1);
println!("Mmm, {}", s2);
}

А защо това е проблем при String, а не при литералите?

А защо това е проблем при String, а не при литералите?

Литералите използват статична памет, която не може да бъде променяна

Клониране

trait Clone

Клониране

trait Clone

Клониране

trait Clone

Клониране

Ако сме сигурни, че искаме да клонираме низа, може да използваме .clone()

1 2 3 4 5
let s1 = String::from("Cookies!");
let s2 = s1.clone();

println!("{}", s1);
println!("Mmm, {}", s2);
Cookies! Mmm, Cookies!
fn main() {
let s1 = String::from("Cookies!");
let s2 = s1.clone();

println!("{}", s1);
println!("Mmm, {}", s2);
}

Клониране и копиране

trait Copy

Клониране и копиране

trait Copy

Клониране и копиране

trait Copy

Клониране и копиране

trait Copy

Копиране

Числените типове имплементират Copy

1 2 3 4 5 6
let n1 = 0xbeef;
let n2 = n1;         // копира s2
let n3 = n1.clone(); // еквивалентно на `n3 = n1`

println!("{}", n2);
println!("Mmm, {:#x}", n3);
48879 Mmm, 0xbeef
fn main() {
let n1 = 0xbeef;
let n2 = n1;         // копира s2
let n3 = n1.clone(); // еквивалентно на `n3 = n1`

println!("{}", n2);
println!("Mmm, {:#x}", n3);
}

Собственост

Ownership

Собственост и заемане

Собственост

1 2 3 4 5
{
    let a = 123;

    // ...
}

Собственост и заемане

Собственост

1 2 3 4 5
{
    let a = 123;

    // ...
}

Собственост

Правила

Собственост

Правила

Собственост

Правила

Собственост

Правила

Собственост

Функции с подаване на String

При подаването на аргументи към функция важат същите семантики

1 2 3 4 5 6 7 8 9 10 11
fn main() {
    let s = String::from("hello"); // Дефинираме s

    takes_ownership(s);            // Стойността на s се мести във функцията и
                                   // затова не е валидна след този ред.

} // Тук s излиза от scope, но s е преместен и съответно не се деалокация.

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
} // some_string излиза от scope и се освобождава паметта.
hello
fn main() {
    let s = String::from("hello"); // Дефинираме s

    takes_ownership(s);            // Стойността на s се мести във функцията и
                                   // затова не е валидна след този ред.

} // Тук s излиза от scope, но s е преместен и съответно не се деалокация.

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
} // some_string излиза от scope и се освобождава паметта.

Собственост

Функции с подаване на число

При подаването на аргументи към функция важат същите семантики

1 2 3 4 5 6 7 8 9 10 11 12 13 14
fn main() {
    let x = 5;     // Дефинираме x

    makes_copy(x); // Тук стойността на x би се преместила във функцията,
                   // но i32 е Copy, затова може да използваме x в последствие.

    println!("This was a triumph");
    println!("x is still alive");
    println!("with the value of {}", x);
} // Тук x излиза от scope.

fn makes_copy(some_integer: i32) {
    println!("{}", some_integer);
} // some_integer излиза от scope, но не се случва нищо особено.
5 This was a triumph x is still alive with the value of 5
fn main() {
    let x = 5;     // Дефинираме x

    makes_copy(x); // Тук стойността на x би се преместила във функцията,
                   // но i32 е Copy, затова може да използваме x в последствие.

    println!("This was a triumph");
    println!("x is still alive");
    println!("with the value of {}", x);
} // Тук x излиза от scope.

fn makes_copy(some_integer: i32) {
    println!("{}", some_integer);
} // some_integer излиза от scope, но не се случва нищо особено.

Собственост

Функции които връщат стойност

Връщането на стойност от функция също може да прехвърля собственост

1 2 3 4 5 6 7 8 9 10 11 12 13 14
fn main() {
    let s1 = gives_ownership();
    let s2 = String::from("hello");
    let s3 = takes_and_gives_back(s2);
}

fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string       // Тук местим стойността към функцията която е извикала gives_ownership
}

fn takes_and_gives_back(a_string: String) -> String {
    a_string
}
fn main() {
    let s1 = gives_ownership();
    let s2 = String::from("hello");
    let s3 = takes_and_gives_back(s2);
}

fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string       // Тук местим стойността към функцията която е извикала gives_ownership
}

fn takes_and_gives_back(a_string: String) -> String {
    a_string
}

Собственост

Функции

А как може да продължим да използваме стойността след извикването на функцията?

Собственост

Функции

А как може да продължим да използваме стойността след извикването на функцията?

1 2 3 4 5 6 7 8 9 10 11
fn main() {
    let s1 = String::from("hello");
    let (s2, len) = calculate_length(s1);

    println!("The length of '{}' is {}.", s2, len);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len() връща дължината на String.
    (s, length)
}
The length of 'hello' is 5.
fn main() {
    let s1 = String::from("hello");
    let (s2, len) = calculate_length(s1);

    println!("The length of '{}' is {}.", s2, len);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len() връща дължината на String.
    (s, length)
}

Собственост и заемане

А какво ако искаме да използваме стойност във функция без да я местим всеки път?

Заемане на стойност (borrowing)

Референции

1 2 3 4 5 6 7 8 9 10
fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}
The length of 'hello' is 5.
fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

Референции

Immutable

Референции

Immutable

Референции

Immutable

Референции

Представяне

Референции

Immutable

1 2 3 4 5 6 7 8 9
fn main() {
    let s = String::from("hello");
    change(&s);
    println!("{}", s);
}

fn change(some_string: &String) {
    some_string.push_str(", world");
}

Референции

Immutable

1 2 3 4 5 6 7 8 9
fn main() {
    let s = String::from("hello");
    change(&s);
    println!("{}", s);
}

fn change(some_string: &String) {
    some_string.push_str(", world");
}
error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` reference --> src/bin/main_7a8d06574d6b81de9d7bcefd13a155afc2a3b55a.rs:8:5 | 7 | fn change(some_string: &String) { | ------- help: consider changing this to be a mutable reference: `&mut String` 8 | some_string.push_str(", world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable For more information about this error, try `rustc --explain E0596`. error: could not compile `rust` due to previous error
fn main() {
    let s = String::from("hello");
    change(&s);
    println!("{}", s);
}

fn change(some_string: &String) {
    some_string.push_str(", world");
}

Референции

Мutable

Референции

Мutable

Референции

Мutable

Референции

Мutable

1 2 3 4 5 6 7 8 9
fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}
hello, world
fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

Референции

Правила

Референции

Правила

Референции

Валидност

1 2 3 4 5 6 7
let r;
{
    let s = String::from("hello");
    r = &s;
}

println!("{}", r);

Референции

Валидност

1 2 3 4 5 6 7
let r;
{
    let s = String::from("hello");
    r = &s;
}

println!("{}", r);
error[E0597]: `s` does not live long enough --> src/bin/main_57ddabce60a0b2fc70095675e3a4176d6ec3e3dc.rs:5:9 | 5 | r = &s; | ^^ borrowed value does not live long enough 6 | } | - `s` dropped here while still borrowed 7 | 8 | println!("{}", r); | - borrow later used here For more information about this error, try `rustc --explain E0597`. error: could not compile `rust` due to previous error
fn main() {
let r;
{
    let s = String::from("hello");
    r = &s;
}

println!("{}", r);
}

Референции

Правила

Референции

Правила

Референции

Правила

Референции

Правила

Референции

Правила

Borrow checker

1 2 3 4 5 6
let mut s = String::from("hello");

let r1 = &mut s;
let r2 = &mut s;

println!("{}, {}", r1, r2);

Borrow checker

1 2 3 4 5 6
let mut s = String::from("hello");

let r1 = &mut s;
let r2 = &mut s;

println!("{}, {}", r1, r2);
error[E0499]: cannot borrow `s` as mutable more than once at a time --> src/bin/main_5bdec4f559fb3cb8b422d5856bd844f38ad67a0f.rs:5:10 | 4 | let r1 = &mut s; | ------ first mutable borrow occurs here 5 | let r2 = &mut s; | ^^^^^^ second mutable borrow occurs here 6 | 7 | println!("{}, {}", r1, r2); | -- first borrow later used here For more information about this error, try `rustc --explain E0499`. error: could not compile `rust` due to previous error
fn main() {
let mut s = String::from("hello");

let r1 = &mut s;
let r2 = &mut s;

println!("{}, {}", r1, r2);
}

Borrow checker

Решение: не ги използвайте заедно

1 2 3 4 5 6 7
let mut s = String::from("hello");

let r1 = &mut s;
println!("{}", r1);

let r2 = &mut s;
println!("{}", r2);
hello hello
#![allow(unused_variables)]
fn main() {
let mut s = String::from("hello");

let r1 = &mut s;
println!("{}", r1);

let r2 = &mut s;
println!("{}", r2);
}

Borrow checker

За повече яснота за живота на r1:

1 2 3 4 5 6 7 8 9
let mut s = String::from("hello");

{
    let r1 = &mut s;
    println!("{}", r1);
}

let r2 = &mut s;
println!("{}", r2);
hello hello
fn main() {
let mut s = String::from("hello");

{
    let r1 = &mut s;
    println!("{}", r1);
}

let r2 = &mut s;
println!("{}", r2);
}

Borrow checker

Не можем да преместим стойност докато има референция към нея

1 2 3 4 5
let s1 = String::from("hello");
let r = &s1;

let s2 = s1;
println!("{}", r);
error[E0505]: cannot move out of `s1` because it is borrowed --> src/bin/main_81fbc5758c4c34a72422dd0521641f6895111026.rs:5:10 | 3 | let r = &s1; | --- borrow of `s1` occurs here 4 | 5 | let s2 = s1; | ^^ move out of `s1` occurs here 6 | println!("{}", r); | - borrow later used here For more information about this error, try `rustc --explain E0505`. error: could not compile `rust` due to previous error
fn main() {
let s1 = String::from("hello");
let r = &s1;

let s2 = s1;
println!("{}", r);
}

Референции

Към скрита (shadowed) променлива

1 2 3 4 5 6 7
let s = String::from("first");
let r = &s;

let s = String::from("second");

println!("{}", r);
println!("{}", s);

Референции

Към скрита (shadowed) променлива

1 2 3 4 5 6 7
let s = String::from("first");
let r = &s;

let s = String::from("second");

println!("{}", r);
println!("{}", s);
first second
fn main() {
let s = String::from("first");
let r = &s;

let s = String::from("second");

println!("{}", r);
println!("{}", s);
}

Референции

Към скрита (shadowed) променлива

1 2 3 4
let s = String::from("hello");
let s = &s;

println!("{}", s);

Референции

Към скрита (shadowed) променлива

1 2 3 4
let s = String::from("hello");
let s = &s;

println!("{}", s);
hello
fn main() {
let s = String::from("hello");
let s = &s;

println!("{}", s);
}

Референции

Към временна стойност

1 2 3
let s = &String::from("hello");

println!("{}", s);
hello
fn main() {
let s = &String::from("hello");

println!("{}", s);
}

Референции

Към временна стойност

1 2 3
let s = &mut String::from("hello");

println!("{}", s);
hello
fn main() {
let s = &mut String::from("hello");

println!("{}", s);
}

Референции

mutable → immutable

1 2 3 4 5 6 7 8 9 10
fn main() {
    let mut s = String::from("hello");
    let r = &mut s;

    greet_cookies(r);
}

fn greet_cookies(greeting: &String) {
    println!("{}, cookies", greeting);
}
fn main() {
    let mut s = String::from("hello");
    let r = &mut s;

    greet_cookies(r);
}

fn greet_cookies(greeting: &String) {
    println!("{}, cookies", greeting);
}

Референции

mutable → immutable

1 2 3 4 5 6 7 8 9 10
fn main() {
    let mut s = String::from("hello");
    let r = &mut s;

    greet_cookies(r);
}

fn greet_cookies(greeting: &String) {
    println!("{}, cookies", greeting);
}
hello, cookies
fn main() {
    let mut s = String::from("hello");
    let r = &mut s;

    greet_cookies(r);
}

fn greet_cookies(greeting: &String) {
    println!("{}, cookies", greeting);
}

Референции

mutable → mutable

1 2 3 4 5 6 7 8 9 10 11
fn main() {
    let mut s = String::from("mmm");
    let r = &mut s;

    get_cookies(r);
    println!("{}", r);
}

fn get_cookies(s: &mut String) {
    s.push_str(", cookies");
}
fn main() {
    let mut s = String::from("mmm");
    let r = &mut s;

    get_cookies(r);
    println!("{}", r);
}

fn get_cookies(s: &mut String) {
    s.push_str(", cookies");
}

Референции

mutable → mutable

1 2 3 4 5 6 7 8 9 10 11
fn main() {
    let mut s = String::from("mmm");
    let r = &mut s;

    get_cookies(r);
    println!("{}", r);
}

fn get_cookies(s: &mut String) {
    s.push_str(", cookies");
}
mmm, cookies
fn main() {
    let mut s = String::from("mmm");
    let r = &mut s;

    get_cookies(r);
    println!("{}", r);
}

fn get_cookies(s: &mut String) {
    s.push_str(", cookies");
}

Низове

Литерали

1
let s: &str = "hello";
fn main() {
let s: &str = "hello";
}

Низове

Литерали

1
let s: &str = "hello";
fn main() {
let s: &str = "hello";
}

Низове

Литерали

1
let s: &str = "hello";
fn main() {
let s: &str = "hello";
}

Низове

Литерали

1
let s: &str = "hello";
fn main() {
let s: &str = "hello";
}

Низове

Литерали

1
let s: &str = "hello";
fn main() {
let s: &str = "hello";
}

Низове

Литерали

1
let s: &str = "hello";
fn main() {
let s: &str = "hello";
}

Низове

String

1
let s = String::from("hello");
fn main() {
let s = String::from("hello");
}

Низове

String

1
let s = String::from("hello");
fn main() {
let s = String::from("hello");
}

Низове

String

1
let s = String::from("hello");
fn main() {
let s = String::from("hello");
}

Низове

String

1
let s = String::from("hello");
fn main() {
let s = String::from("hello");
}

Низове

Slices

Можем да вземем част от низ

1 2 3 4 5
let s = String::from("hello, world");
let r1 = &s[..];
let r2 = &r1[1..4];

println!("{}", r2);
ell
#![allow(unused_variables)]
fn main() {
let s = String::from("hello, world");
let r1 = &s[..];
let r2 = &r1[1..4];

println!("{}", r2);
}

Низове

Slices

Низове

Slices

Низове

Slices

Низове

Slices

Типа &str

Типа &str

Типа &str

Типа &str

Типа &str

            my_name: String   last_name: &str
            [––––––––––––]    [–––––––]
            +–––+––––+––––+–––+–––+–––+
stack frame │ • │ 16 │ 13 │   │ • │ 6 │
            +–│–+––––+––––+–––+–│–+–––+
              │                 │
              │                 +–––––––––+
              │                           │
              │                           │
              │                         [–│––––––– str –––––––––]
            +–V–+–––+–––+–––+–––+–––+–––+–V–+–––+–––+–––+–––+–––+–––+–––+–––+
       heap │ P │ a │ s │ c │ a │ l │   │ P │ r │ e │ c │ h │ t │   │   │   │
            +–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+

Типа &mut str

Типа &mut str

Типа &mut str

Типа &mut str

Вектори

Tипа Vec

1 2 3 4 5 6
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

println!("{:?}", v);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

println!("{:?}", v);
}

Вектори

Tипа Vec

1 2 3 4 5 6
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

println!("{:?}", v);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

println!("{:?}", v);
}

Вектори

Tипа Vec

1 2 3 4 5 6
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

println!("{:?}", v);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);

println!("{:?}", v);
}

Вектори

макрото vec!

1 2 3
let v = vec![1, 2, 3];

println!("{:?}", v);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let v = vec![1, 2, 3];

println!("{:?}", v);
}

Типа &[T]

Типа &[T]

Типа &[T]

Типа &[T]

&[T]

Резен от масив

1 2 3 4
let arr = [1, 2, 3];
let slice = &arr[..];

println!("{:?}", slice);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let arr = [1, 2, 3];
let slice = &arr[..];

println!("{:?}", slice);
}

&[T]

Резен от масив литерал

1 2 3
let slice = &[1, 2, 3];

println!("{:?}", slice);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let slice = &[1, 2, 3];

println!("{:?}", slice);
}

&[T]

Резен от вектор

1 2 3 4
let v = vec![1, 2, 3];
let slice = &v[..];

println!("{:?}", slice);
[1, 2, 3]
#![allow(unused_variables)]
fn main() {
let v = vec![1, 2, 3];
let slice = &v[..];

println!("{:?}", slice);
}

Въпроси