упр.08 задача 1
- Краен срок:
- 03.12.2025 23:59
- Точки:
- 4
Срокът за предаване на решения е отминал
Забележка: погледнете слайдовете за
RcиRefCellпреди да решавате задачата - линк
Имплементирайте структура от данни persistent linked list.
Persistent структурите от данни се различават с това, че са immutable и операциите върху тях не модифицират оригиналната структура, ами връщат нова обновена версия. Обикновенно новата версия преизползва памет от старата версия.
Имат предимства и недостатъци и са по-популярни в чисто функционалните езици, отколкото в Rust.
Персистентния свързан списък би изглеждал така:
list1 -> A ---v
list2 ------> B -> C -> D
list3 -> X ---^
Използвайте следната структура:
struct List<T> {
head: Link<T>,
}
type Link<T> = Option<Rc<Node<T>>>;
struct Node<T> {
elem: T,
next: Link<T>,
}
Имплементирайте следните методи върху List:
// Създава празен списък
fn new() -> Self
// Връща първия елемент от списъка
fn head(&self) -> Option<&T>
// Връща опашката на списъка - т.е. списък съдържащ
// всички елементи освен първия.
// Опашката на празен списък е празен списък.
fn tail(&self) -> List<T>
// Добавя елемент към списъка.
// Връща нов списък с първи елемент е `value` и
// опашка стария списък.
fn prepend(&self, value: T) -> List<T>
// Създава итератор по елементите на списъка.
// Итератора връща елементи от тип `&T`.
fn iter(&self) -> Iter<'_, T>
Имплементирайте trait Iterator за структурата Iter.
Итерацията не би трябвало да създава копия на Rc.
Опитайте се да работите с &Node<T> вместо Rc<Node<T>>.
Съвети:
- внимавайте за конкретните типове на стойностите. Не забравяйте, че ако нещо не е ясно може да слагате експлицитен тип (
let some_var: T =) като type assertion. - разгледайте какви методи има върху типовете. Някои примери, които могат да са ви полезни:
- Option::as_ref:
fn (&Option<T>) -> Option<&T> - Option::as_mut:
fn (&mut Option<T>) -> Option<&mut T> - Option::map:
fn (Option<T>, fn(T)->U) -> Option<U> - Option::take =
std::mem::replace(&mut option_variable, None)
- Option::as_ref:
Бонус (1т.)
Помислете защо следния код гърми със fatal runtime error: stack overflow.
Имплементирайте решение.
fn main() {
let mut list = List::new();
for i in 0..1_000_000 {
list = list.prepend(i);
}
std::mem::drop(list);
}
Задължително прочетете (или си припомнете): Указания за предаване на домашни
Погрижете се решението ви да се компилира с базовия тест:
