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

13 октомври 2026

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

Структури

1 2 3 4 5 6 7 8 9
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};
fn main() {
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};
}

Структури

1 2 3 4 5 6 7 8 9 10 11
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};

println!("имейл: {}, влизания: {}", user1.email, user1.sign_in_count);
имейл: user@example.com, влизания: 0
fn main() {
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};

println!("имейл: {}, влизания: {}", user1.email, user1.sign_in_count);
}

Структури

1 2 3 4 5 6 7 8 9 10 11
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};

println!("потребител: {:?}", user1);
error[E0277]: `User` doesn't implement `Debug` --> src/bin/main_a1661ab76f33beb5d4f2d7f48e9583162333d530.rs:12:30 | 12 | println!("потребител: {:?}", user1); | ---- ^^^^^ `User` cannot be formatted using `{:?}` because it doesn't implement `Debug` | | | required by this formatting parameter | = help: the trait `Debug` is not implemented for `User` help: consider annotating `User` with `#[derive(Debug)]` | 2 + #[derive(Debug)] 3 | struct User { | For more information about this error, try `rustc --explain E0277`. error: could not compile `rust` (bin "main_a1661ab76f33beb5d4f2d7f48e9583162333d530") due to 1 previous error
fn main() {
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};

println!("потребител: {:?}", user1);
}

Структури

1 2 3 4 5 6 7 8 9 10 11 12
#[derive(Debug)]
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};

println!("потребител: {:?}", user1);
потребител: User { email: "user@example.com", sign_in_count: 0 }
fn main() {
#[derive(Debug)]
struct User {
    email: String,
    sign_in_count: u32,
}

let user1 = User {
    email: "user@example.com".to_string(),
    sign_in_count: 0,
};

println!("потребител: {:?}", user1);
}

Структури

derive

1 2
#[derive(Debug)]
struct User {

Собственост

Преместване

1 2 3 4 5 6
let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

println!("user1: {:?}", user1);
user1: User { email: "foo@example.com", sign_in_count: 0 }
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

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

Собственост

Преместване

1 2 3 4 5 6 7
let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;
println!("user2: {:?}", user2);
user2: User { email: "foo@example.com", sign_in_count: 0 }
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;
println!("user2: {:?}", user2);
}

Собственост

Преместване

1 2 3 4 5 6 7
let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;
println!("user2: {:?}", user2);
user2: User { email: "foo@example.com", sign_in_count: 0 }
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;
println!("user2: {:?}", user2);
}

Собственост

Преместване

1 2 3 4 5 6 7
let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;
println!("user2: {:?}", user2);
user2: User { email: "foo@example.com", sign_in_count: 0 }
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;
println!("user2: {:?}", user2);
}

Собственост

Преместване

След присвояване старата променлива не може да се достъпва.
Опит за това връща компилационна грешка: use of moved value.

1 2 3 4 5 6 7 8 9
let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;

println!("user2: {:?}", user2);
println!("user1: {:?}", user1);
error[E0382]: borrow of moved value: `user1` --> src/bin/main_f8a53c25bfbf58232d883fce5edc9e6360290642.rs:13:25 | 5 | let user1 = User { | ----- move occurs because `user1` has type `User`, which does not implement the `Copy` trait ... 10 | let user2 = user1; | ----- value moved here ... 13 | println!("user1: {:?}", user1); | ^^^^^ value borrowed here after move | note: if `User` implemented `Clone`, you could clone the value --> src/bin/main_f8a53c25bfbf58232d883fce5edc9e6360290642.rs:3:1 | 3 | struct User { email: String, sign_in_count: u32 } | ^^^^^^^^^^^ consider implementing `Clone` for this type ... 10 | let user2 = user1; | ----- you could clone this value For more information about this error, try `rustc --explain E0382`. error: could not compile `rust` (bin "main_f8a53c25bfbf58232d883fce5edc9e6360290642") due to 1 previous error
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};

let user2 = user1;

println!("user2: {:?}", user2);
println!("user1: {:?}", user1);
}

Собственост

Преместване

Собственост

Преместване

Собственост

Преместване

Преместването не се води модифициране на стойността - не изисква mutable binding.

1 2
let user1 = ...; // няма `mut`
let user2 = user1;

Собственост

Преместване

Преместването може да се използва за да променим дали дадена стойност е зад mutable или immutable binding.
…

1 2 3 4 5
let user = ...;
let mut user2 = user;

let mut user = ...;
let user2 = user;

Собственост

Преместване

Преместването може да се използва за да променим дали дадена стойност е зад mutable или immutable binding.
(Това е един добър повод за ползване на засенчване на променливи.)

1 2 3 4 5
let user = ...;
let mut user = user;

let mut user = ...;
let user = user;

Собственост

Клониране

Вместо да преместваме стойността, можем да направим копие с метода clone().
Копирането е експицитно.

1 2 3 4 5
let email1 = String::from("foo@example.com");
let email2 = email1.clone();

println!("email1: {}", email1);
println!("email2: {}", email2);
email1: foo@example.com email2: foo@example.com
fn main() {
let email1 = String::from("foo@example.com");
let email2 = email1.clone();

println!("email1: {}", email1);
println!("email2: {}", email2);
}

Собственост

Клониране

Типове дефинирани от нас по подразбиране не поддържат clone().
…

1 2 3 4 5 6 7 8
//
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};
let user2 = user1.clone();
error[E0599]: no method named `clone` found for struct `User` in the current scope --> src/bin/main_ef76d58f80b783af858ae2f9af0b8ae3232baf3f.rs:9:19 | 3 | struct User { email: String, sign_in_count: u32 } | ----------- method `clone` not found for this struct ... 9 | let user2 = user1.clone(); | ^^^^^ method not found in `User` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` For more information about this error, try `rustc --explain E0599`. error: could not compile `rust` (bin "main_ef76d58f80b783af858ae2f9af0b8ae3232baf3f") due to 1 previous error
fn main() {
//
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};
let user2 = user1.clone();
}

Собственост

Клониране

Типове дефинирани от нас по подразбиране не поддържат clone().
Ако искаме, трябва да го имплементираме с derive(Clone).

1 2 3 4 5 6 7 8
#[derive(Clone)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};
let user2 = user1.clone();
fn main() {
#[derive(Clone)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};
let user2 = user1.clone();
}

Собственост

Клониране

Типове дефинирани от нас по подразбиране не поддържат clone().
Ако искаме, трябва да го имплементираме с derive(Clone).

1 2 3 4 5 6 7 8 9 10 11
#[derive(Clone, Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};
let user2 = user1.clone();

println!("user1: {:?}", user1);
println!("user2: {:?}", user2);
user1: User { email: "foo@example.com", sign_in_count: 0 } user2: User { email: "foo@example.com", sign_in_count: 0 }
fn main() {
#[derive(Clone, Debug)]
struct User { email: String, sign_in_count: u32 }

let user1 = User {
    email: "foo@example.com".to_string(),
    sign_in_count: 0,
};
let user2 = user1.clone();

println!("user1: {:?}", user1);
println!("user2: {:?}", user2);
}

Собственост

Копиране

Някои типове поддръжат семантика на копирането.
При тях присвояването води до копиране на стойността.
След това и старата и новата променлива могат да се използват.

1 2 3 4 5
let n1 = 123;
let n2 = n1;

println!("{}", n1);
println!("{}", n2);
123 123
fn main() {
let n1 = 123;
let n2 = n1;

println!("{}", n1);
println!("{}", n2);
}

Собственост

Копиране

Собственост

Копиране

Собственост

Копиране

Собственост

Копиране

Референции

Референции

Референции

Референции

1 2 3 4 5 6 7 8 9 10
fn print_user(user: &User) {
    println!("потребител {} (влизания {})", user.email, user.sign_in_count);
}

let user1 = User {
    /* ... */
};

print_user(&user1);
print_user(&user1);
потребител foo@example.com (влизания 444) потребител foo@example.com (влизания 444)
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

fn print_user(user: &User) {
    println!("потребител {} (влизания {})", user.email, user.sign_in_count);
}

let user1 = User {
    /* ... */
email: "foo@example.com".to_string(),
sign_in_count: 444,
};

print_user(&user1);
print_user(&user1);
}

Референции

1 2 3 4 5 6 7 8 9 10 11
fn print_user(user: &User) {
    println!("потребител {} (влизания {})", user.email, user.sign_in_count);
}

let user1 = User {
    /* ... */
};

let user_ref: &User = &user1;
print_user(user_ref);
print_user(user_ref);
потребител foo@example.com (влизания 444) потребител foo@example.com (влизания 444)
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }

fn print_user(user: &User) {
    println!("потребител {} (влизания {})", user.email, user.sign_in_count);
}

let user1 = User {
    /* ... */
email: "foo@example.com".to_string(),
sign_in_count: 444,
};

let user_ref: &User = &user1;
print_user(user_ref);
print_user(user_ref);
}

Референции

Референции

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
fn check_and_sign_in(user: &mut User, email: &str) -> bool {
    if user.email == email {
        user.sign_in_count += 1;
        true
    } else {
        false
    }
}

let mut user1 = User {
    /* ... */
};

print_user(&user1);
check_and_sign_in(&mut user1, "foo@example.com");
print_user(&user1);
потребител foo@example.com (влизания 0) потребител foo@example.com (влизания 1)
fn main() {
#[derive(Debug)]
struct User { email: String, sign_in_count: u32 }
fn print_user(user: &User) { println!("потребител {} (влизания {})", user.email, user.sign_in_count); }

fn check_and_sign_in(user: &mut User, email: &str) -> bool {
    if user.email == email {
        user.sign_in_count += 1;
        true
    } else {
        false
    }
}

let mut user1 = User {
    /* ... */
email: "foo@example.com".to_string(),
sign_in_count: 0,
};

print_user(&user1);
check_and_sign_in(&mut user1, "foo@example.com");
print_user(&user1);
}

Валидност

Lifetime на променлива - напълно стандартно:

1 2 3 4
fn main() {
    let user1 = User { /* ... */ };

} // <---- `user1` се унищожава

Валидност

Lifetime на референиця:

1 2 3 4 5 6 7 8 9 10 11
fn main() {
    let user1 = User { /* ... */ };  // --------+
                                     //         |
    let ref1 = &user1;  // ---------------+     |
    let ref2 = &user1;  // ---------------+--+  |
                        //                |  |  |
    println!("first: {:?}", ref1);   //   |  |  |
                                     // <-+  |  |
    println!("seconds: {:?}", ref2); //      |  |
                                     // <----+  |
}   // <----------------------------------------+

Валидност

Валидност

Валидност

Валидност

Валидност

1 2 3 4 5 6 7 8 9 10
let user = User {
    /* ... */
};

let user_ref = &user;

// грешка: cannot move out of `user` because it is borrowed
let new_user = user;

println!("{:?}", user_ref);
error[E0505]: cannot move out of `user` because it is borrowed --> src/bin/main_fa66e6edff560b5c8aaa445e44adbf1d5f1dcaaf.rs:14:16 | 5 | let user = User { | ---- binding `user` declared here ... 11 | let user_ref = &user; | ----- borrow of `user` occurs here ... 14 | let new_user = user; | ^^^^ move out of `user` occurs here 15 | 16 | println!("{:?}", user_ref); | -------- borrow later used here | help: consider cloning the value if the performance cost is acceptable | 11 | let user_ref = &user.clone(); | ++++++++ For more information about this error, try `rustc --explain E0505`. error: could not compile `rust` (bin "main_fa66e6edff560b5c8aaa445e44adbf1d5f1dcaaf") due to 1 previous error
#[derive(Clone, Debug)]
struct User { email: String, sign_in_count: u32 }

fn main() {
let user = User {
    /* ... */
email: "foo@example.com".to_string(),
sign_in_count: 0,
};

let user_ref = &user;

// грешка: cannot move out of `user` because it is borrowed
let new_user = user;

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

Валидност

1 2 3 4 5 6 7 8 9 10 11
let user = User {
    /* ... */
};

let user_ref = &user;
// `user_ref` не се използва след този ред

// преместване от `user` - OK
let new_user = user;

// println!("{:?}", user_ref);
#[derive(Clone, Debug)]
struct User { email: String, sign_in_count: u32 }

fn main() {
let user = User {
    /* ... */
email: "foo@example.com".to_string(),
sign_in_count: 0,
};

let user_ref = &user;
// `user_ref` не се използва след този ред

// преместване от `user` - OK
let new_user = user;

// println!("{:?}", user_ref);
}

Валидност

1 2 3 4 5 6 7 8
fn main() {
    let user1 = User { /* ... */ };

    {
        let user_ref = &user1;
    } // <--+
      //    | OK - user_ref се "унищожава" преди user1
}

Валидност

1 2 3 4 5
fn main() {
    let user1 = User { /* ... */ };
    let user_ref = &user1;
}  // <--+
   //    | OK - user_ref се "унищожава" преди user1

Валидност

1 2 3 4 5 6 7 8
fn main() {
    let user_ref = {
        let user1 = User { /* ... */ };

        &user1
    }; // <--+
       //    | грешка - user1 се унищожава преди user_ref
}

Валидност

1 2 3 4 5 6 7 8 9 10 11 12 13 14
fn main() {
    let empty_email = String::new();
    let mut email_ref = &empty_email[..];

    {
        let user1 = User {
            /* ... */
        };

        email_ref = &user1.email;
    };

    println!("{}", email_ref);
}
error[E0597]: `user1.email` does not live long enough --> src/bin/main_7c4924a93304e9d9eaba1247515b3e982b24fef8.rs:13:21 | 7 | let user1 = User { | ----- binding `user1` declared here ... 13 | email_ref = &user1.email; | ^^^^^^^^^^^^ borrowed value does not live long enough 14 | }; | - `user1.email` dropped here while still borrowed 15 | 16 | println!("{}", email_ref); | --------- borrow later used here For more information about this error, try `rustc --explain E0597`. error: could not compile `rust` (bin "main_7c4924a93304e9d9eaba1247515b3e982b24fef8") due to 1 previous error
struct User { email: String, sign_in_count: u32 }
fn main() {
    let empty_email = String::new();
    let mut email_ref = &empty_email[..];

    {
        let user1 = User {
            /* ... */
email: "".to_string(),
sign_in_count: 0,
        };

        email_ref = &user1.email;
    };

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

Валидност

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
fn main() {
    let empty_email = String::new();
    let mut email_ref = &empty_email[..];

    {
        let user1 = User {
            /* ... */
        };

        email_ref = get_user_email(&user1);
    };

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

fn get_user_email(user: &User) -> &str {
    &user.email
}
error[E0597]: `user1` does not live long enough --> src/bin/main_d31014a3fdf35ce3c6dbef96c1002b613d0e4934.rs:13:36 | 7 | let user1 = User { | ----- binding `user1` declared here ... 13 | email_ref = get_user_email(&user1); | ^^^^^^ borrowed value does not live long enough 14 | }; | - `user1` dropped here while still borrowed 15 | 16 | println!("{}", email_ref); | --------- borrow later used here For more information about this error, try `rustc --explain E0597`. error: could not compile `rust` (bin "main_d31014a3fdf35ce3c6dbef96c1002b613d0e4934") due to 1 previous error
struct User { email: String, sign_in_count: u32 }
fn main() {
    let empty_email = String::new();
    let mut email_ref = &empty_email[..];

    {
        let user1 = User {
            /* ... */
email: "".to_string(),
sign_in_count: 0,
        };

        email_ref = get_user_email(&user1);
    };

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

fn get_user_email(user: &User) -> &str {
    &user.email
}

Borrow checker

Borrow checker

Правило

Borrow checker

Правило

Borrow checker

Правило

Borrow checker

Защо?

Borrow checker

Защо?

Borrow checker

Защо?

Borrow checker

Защо?

Borrow checker

Защо?

Borrow checker

Защо?

Borrow checker

Защо?

Класически пример за грешка - инвалидация на итератори

1 2 3 4 5 6 7 8 9
let mut vec = vec![1, 2, 3];

for val in vec.iter() {
    do_something(val);

    if some_condition {
        vec.push(99);
    }
}
error[E0502]: cannot borrow `vec` as mutable because it is also borrowed as immutable --> src/bin/main_9036c0a5609ad39a3ebd2868f8e68cf6133e5a72.rs:10:9 | 6 | for val in vec.iter() { | ---------- | | | immutable borrow occurs here | immutable borrow later used here ... 10 | vec.push(99); | ^^^^^^^^^^^^ mutable borrow occurs here For more information about this error, try `rustc --explain E0502`. error: could not compile `rust` (bin "main_9036c0a5609ad39a3ebd2868f8e68cf6133e5a72") due to 1 previous error
fn main() {
fn do_something(_: &i32) {}
let some_condition = false;
let mut vec = vec![1, 2, 3];

for val in vec.iter() {
    do_something(val);

    if some_condition {
        vec.push(99);
    }
}
}

Низове

Низове

String

Низове

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

1
let greeting = String::from("Hello, Rust");
fn main() {
let greeting = String::from("Hello, Rust");
}



            [–––– greeting: String ––––]
            +––––––––+––––––––+––––––––+
stack frame │ ptr=•  │ cap=16 │ len=11 │
            +–––––│––+––––––––+––––––––+
              +–––+
              │
              │
            [–│–––––––––––––––––– ptr + len ––––––––––––]
            [-│------------------ ptr + cap --------------------------------]
            +–V–+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+
       heap │ H │ e │ l │ l │ o │ , │ ␣ │ R │ u │ s │ t │   │   │   │   │   │
            +–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+

Низове

String

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

hello.push('w');
hello.push_str("orld!");

println!("{:?}", hello);
"Hello, world!"
fn main() {
let mut hello = String::from("Hello, ");

hello.push('w');
hello.push_str("orld!");

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

Низове

&str

Низове

Разполагане в паметта (&str)

1 2
let greeting = String::from("Hello, Rust");
let greeting_slice = greeting.as_str();
fn main() {
let greeting = String::from("Hello, Rust");
let greeting_slice = greeting.as_str();
}


            [–––– greeting: String ––––]  [greeting_slice: &str]
            +––––––––+––––––––+––––––––+  +–––––––––+–––––––––+
stack frame │ ptr=•  │ cap=16 │ len=11 │  │  ptr=•  │  len=11 │
            +–––––│––+––––––––+––––––––+  +––––––│––+–––––––––+
             +––––+                              │
             │ +–––––––––––––––––––––––––––––––––+
             │ │
             │ │
            [│–│––––––––––––––––– str ––––––––––––––––––]
            +V–V+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+
       heap │ H │ e │ l │ l │ o │ , │ ␣ │ R │ u │ s │ t │   │   │   │   │   │
            +–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+

Низове

&str

Низове

&str

Низове

Литерали

1
let s: &str = "literal string";

Низове

Литерали

1
let s: &str = "literal string";

Низове

Литерали

1
let s: &str = "literal string";
1
let s: &'static str = "Hello";

Низове

Разполагане в паметта (&str)

1 2
let greeting = "Hello, Rust";
let who = &greeting[7..];
fn main() {
let greeting = "Hello, Rust";
let who = &greeting[7..];
}


            [– greeting: &str –]          [–– who: &str ––]
            +––––––––+––––––––+           +–––––––+–––––––+
stack frame │ ptr=•  │ len=11 │           │ ptr=• │ len=4 │
            +–––––│––+––––––––+           +–––––│–+–––––––+
              +–––+                             │
              │                           +–––––+
              │                           │
              │                           │
              │                         [–│––– str –––––]
            +–V–+–––+–––+–––+–––+–––+–––+–V–+–––+–––+–––+
    .rodata │ H │ e │ l │ l │ o │   │ ␣ │ R │ u │ s │ t │
            +–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+–––+

Низове

Резени

1 2 3 4 5 6 7
let s = "Hello, world";
let hello = &s[0..5];
let world = &s[7..12];

println!("{:?}", s);
println!("{:?}", hello);
println!("{:?}", world);
"Hello, world" "Hello" "world"
fn main() {
let s = "Hello, world";
let hello = &s[0..5];
let world = &s[7..12];

println!("{:?}", s);
println!("{:?}", hello);
println!("{:?}", world);
}

Низове

Резени

1 2 3 4 5 6 7
let s = "Hello, world";
let hello = &s[0..5];
let world = &s[7..12];

println!("{:12}: ptr={:#x} len={}", s, s.as_ptr() as usize, s.len());
println!("{:12}: ptr={:#x} len={}", hello, hello.as_ptr() as usize, hello.len());
println!("{:12}: ptr={:#x} len={}", world, world.as_ptr() as usize, world.len());
Hello, world: ptr=0x5627861b307b len=12 Hello : ptr=0x5627861b307b len=5 world : ptr=0x5627861b3082 len=5
fn main() {
let s = "Hello, world";
let hello = &s[0..5];
let world = &s[7..12];

println!("{:12}: ptr={:#x} len={}", s, s.as_ptr() as usize, s.len());
println!("{:12}: ptr={:#x} len={}", hello, hello.as_ptr() as usize, hello.len());
println!("{:12}: ptr={:#x} len={}", world, world.as_ptr() as usize, world.len());
}

Низове

Интервали

Низове

Интервали

Низове

Интервали

Низове

Интервали

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

let r1 = &s[1..4];
println!("{}", r1);

let r2 = &s[..s.len()-2]; // &s[..-2] не е възможно
println!("{}", r2);

let r3 = &s[..];
println!("{}", r3);
ell hello, wor hello, world
fn main() {
let s = String::from("hello, world");

let r1 = &s[1..4];
println!("{}", r1);

let r2 = &s[..s.len()-2]; // &s[..-2] не е възможно
println!("{}", r2);

let r3 = &s[..];
println!("{}", r3);
}

Низове

Използване

Кога да използвате String?

1 2 3 4 5
struct User {
    first_name: String,
    last_name: String,
    email: String,
}

Низове

Използване

Кога да използвате &str?

1
fn print_names(first: &str, last: &str) { /* ... */ }
1
fn trim_whitespace(s: &str) -> &str { /* ... */ }

Низове

Използване

1 2 3 4 5
let hello = "hello";

let hello2 = format!("{}, again", hello); // : String

println!("{:?}", hello2);
"hello, again"
fn main() {
let hello = "hello";

let hello2 = format!("{}, again", hello); // : String

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

Низове

Използване

1 2 3 4 5 6 7 8
// конвертиране от &str до String
let s = String::from("hello");
let s = "hello".to_string();
let s = "hello".to_owned();

// конвертиране от String до &str
let str_ref = s.as_str();
let str_ref = &s[..];
fn main() {
// конвертиране от &str до String
let s = String::from("hello");
let s = "hello".to_string();
let s = "hello".to_owned();

// конвертиране от String до &str
let str_ref = s.as_str();
let str_ref = &s[..];
}

Низове

Индексиране

1 2 3 4 5
let hello = "Здравей свят";

println!("bytes {}", hello.len());
println!("chars {}", hello.chars().count());
println!("{:?}", &hello[..14]);
bytes 23 chars 12 "Здравей"
fn main() {
let hello = "Здравей свят";

println!("bytes {}", hello.len());
println!("chars {}", hello.chars().count());
println!("{:?}", &hello[..14]);
}

Низове

Индексиране

1 2 3
let hello = "Здравей свят";

println!("{:?}", &hello[..13]);
thread 'main' (10012) panicked at src/bin/main_3b57e62b952095839146965c2229e9511f8e078c.rs:4:24: end byte index 13 is not a char boundary; it is inside 'й' (bytes 12..14 of string) note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fn main() {
let hello = "Здравей свят";

println!("{:?}", &hello[..13]);
}

Низове

Индексиране

1 2 3
let hello = "Здравей свят";

println!("{:?}", hello[2]);
error[E0277]: the type `str` cannot be indexed by `{integer}` --> src/bin/main_07697788709a48545e5e9b9d2fbc0083c5254bc1.rs:4:24 | 4 | println!("{:?}", hello[2]); | ^ string indices are ranges of `usize` | = help: the trait `SliceIndex<str>` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> help: `usize` implements trait `SliceIndex<T>` --> /home/nikola/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:179:1 | 179 | const unsafe impl<T> SliceIndex<[T]> for usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SliceIndex<[T]>` | ::: /home/nikola/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/bstr/traits.rs:197:1 | 197 | unsafe impl SliceIndex<ByteStr> for usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SliceIndex<ByteStr>` = note: required for `str` to implement `Index<{integer}>` For more information about this error, try `rustc --explain E0277`. error: could not compile `rust` (bin "main_07697788709a48545e5e9b9d2fbc0083c5254bc1") due to 1 previous error
fn main() {
let hello = "Здравей свят";

println!("{:?}", hello[2]);
}

Масиви

Масив Низ
статичен [T; N] - собственост над стойността
динамичен Vec<T> String собственост над стойността
резен &[T] &str заета назаем стойност (borrow)
mutable резен &mut [T] &mut str заета назаем стойност (borrow)

Live coding

Пример за четене от стандартния вход

Въпроси