Shanraq.org Shanraq.org
Итераторлар: оқу, өзгерту және иелікті беру
IT

Rust: алғашқы қадамнан жеке жоспарлау құралына дейін 41-сабақ (барлығы 50)

Итераторлар: оқу, өзгерту және иелікті беру

41-сабақ. Тапсырмаларды аралау тәсілін таңдап, деректі мерзімінен бұрын жоғалтпау.

Мәтін ИИ көмегімен аударылды.

Алдын ала: 20-сабақтағы қарызға алу, 24-сабақтағы Vec, 40-сабақтағы жоспарлау құралы. 40-сабақтағы жобаның көшірмесін сақтаңыз: мұнда бір ұғымды анық көру үшін main.rs файлын шағын бағдарламамен толық ауыстырамыз. Бұрынғы іске қосудағы дерек көшпейді.

Таныс бейне және тірек сызба

Кітапханашы сөредегі кітаптарды үш түрлі мақсатпен аралайды: атауын оқиды, тіркеу қағазын түзетеді немесе кітаптарды алып шығады. Итератор — элементтерді бір-бірден беріп, қай жерге келгенін есте сақтайтын нысан. Ұқсатудың шегі — Rust-тағы иелік: iter() ортақ &Task сілтемелерін, iter_mut() өзгертілетін &mut Task сілтемелерін береді; into_iter() элементтерді тізімнен алып, иелікті өткізеді. Соңғысынан кейін бұрынғы Vec қолданылмайды. Иелік пен сілтеме 19–21-сабақтарда түсіндірілген.

Тізім → iter (оқу) / iter_mut (өзгерту) / into_iter (иелікті беру) → келесі элемент не соңы. next() бір қадам жасайды: элемент болса Some, біткенде None қайтарады. let mut reader жазамыз, өйткені әр қадам итератордың орнын өзгертеді. Итераторды жасау тізімді бірден араламайды: ол қажеттілік туғанша күтеді. for циклі элементтер біткенше сұрайды. Мысалдағы үш аралау қатар жүрмейді: оқу біткен соң ғана өзгерту басталады. if let Some(task) элемент табылса ғана ішіндегі әрекетті орындайды. !task.done — «әлі дайын емес» деген шарт.

Іске қосып көріңіз

Жоба бумасында src/main.rs файлын төмендегі кодпен ауыстырып, 6-сабақтан таныс cargo run пәрменін орындаңыз. Қосымша кітапхана қажет емес. Cargo-ның қызметтік хабарлары көрсетілген бағдарлама нәтижесіне кірмейді. Тар экранда ұзын код жолын ашық түсті блоктың ішінде саусақпен көлденең жылжытып оқуға болады; бүкіл бет жылжымайды.

struct Task {
    id: u32,
    title: String,
    done: bool,
}

fn main() {
    let mut tasks = vec![
        Task {
            id: 1,
            title: String::from("Rust оқу"),
            done: false,
        },
        Task {
            id: 2,
            title: String::from("Ойды жазу"),
            done: false,
        },
    ];
    let mut reader = tasks.iter();
    if let Some(task) = reader.next() {
        println!("Алғашқы: {}", task.title);
    }
    for task in tasks.iter_mut() {
        if task.id == 2 {
            task.done = true;
        }
    }
    for task in tasks.iter() {
        println!("Тапсырма {}: {}", task.id, task.title);
    }
    let mut done_count = 0;
    for task in tasks.iter() {
        if task.done {
            done_count += 1;
        }
    }
    println!("Дайын: {}", done_count);
    for task in tasks.into_iter() {
        println!("Иелік етеміз: {}", task.title);
    }
}
Алғашқы: Rust оқу
Тапсырма 1: Rust оқу
Тапсырма 2: Ойды жазу
Дайын: 1
Иелік етеміз: Rust оқу
Иелік етеміз: Ойды жазу

Әуелі бірінші тапсырма оқылады, одан кейін 2-нөмірлі тапсырма дайын деп белгіленеді. Соңғы цикл атаулардың иелігін алады. into_iter() кейін tasks.len() жазу қате: тізімнің иелігі беріліп қойған. Жай көрсету үшін көбіне iter() жеткілікті. Дерек әзірше бір іске қосу уақытында ғана сақталады.

Бетке қарамай еске түсіріңіз

  1. Тапсырманы дайын деп белгілеу үшін қай тәсіл керек?
  2. into_iter() кейін tasks неге оқылмайды?
  3. let reader = tasks.iter() ғана жазылса, тізім аралана ма?

Тапсырма

Міндетті. into_iter() цикліне дейін тағы бір аралаумен аяқталмаған тапсырмалар санын есептеп, Күтіп тұр: 1 шығарыңыз. Өзге жолдардың ретін сақтаңыз. Бұл санаққа иелікті беру неге қажет емес екенін түсіндіріңіз.

Жауаптар

Жауаптарды көрсету

pending_count = 0 мәнін жасаңыз; tasks.iter() арқылы өтіп, !task.done болғанда бір қосыңыз. Мұны into_iter() алдынан орындаңыз.

Талпыныстан кейінгі үлгі жауап

struct Task {
    id: u32,
    title: String,
    done: bool,
}

fn main() {
    let mut tasks = vec![
        Task {
            id: 1,
            title: String::from("Rust оқу"),
            done: false,
        },
        Task {
            id: 2,
            title: String::from("Ойды жазу"),
            done: false,
        },
    ];
    let mut reader = tasks.iter();
    if let Some(task) = reader.next() {
        println!("Алғашқы: {}", task.title);
    }
    for task in tasks.iter_mut() {
        if task.id == 2 {
            task.done = true;
        }
    }
    for task in tasks.iter() {
        println!("Тапсырма {}: {}", task.id, task.title);
    }
    let mut done_count = 0;
    for task in tasks.iter() {
        if task.done {
            done_count += 1;
        }
    }
    println!("Дайын: {}", done_count);
    let mut pending_count = 0;
    for task in tasks.iter() {
        if !task.done {
            pending_count += 1;
        }
    }
    println!("Күтіп тұр: {}", pending_count);
    for task in tasks.into_iter() {
        println!("Иелік етеміз: {}", task.title);
    }
}
Алғашқы: Rust оқу
Тапсырма 1: Rust оқу
Тапсырма 2: Ойды жазу
Дайын: 1
Күтіп тұр: 1
Иелік етеміз: Rust оқу
Иелік етеміз: Ойды жазу

Тексергеннен кейін

Тексеру: санау иелік берілгенге дейін орындалады, ID мен дайындық белгісі өзгермейді. Rust-тың итераторлар туралы ресми тарауы. Сілтемелер шатасса, 20-сабаққа оралыңыз.

Алдыңғы сабақ · Мазмұны

Мәтінде қате не теру қатесі кездессе, бізге айтыңыз

Пікірлер (0)

Әзірге пікір жоқ. Бірінші болыңыз.