Любая из этих реализаций будет технически работать, но есть некоторые большие компромиссы.
A Box
выделяет в куче, а затем владеет данными. Это довольно удобно и гибко по сравнению с управлением ссылками.
Чтобы построить список второго типа, используя ссылки &
, вам нужно где-то владеть данными. Таким образом, вам нужно управлять произвольным количеством узлов и следить за тем, чтобы они не выходили за рамки. Это может быть очень ограничительным. Например, не очень легко создать функцию, которая создает список и затем возвращает его:
fn make_list<'a>() -> List<'a> {
let node1 = List::Nil;
let node2 = List::Cons(1, &node1);
let node3 = List::Cons(2, &node2);
node3
// node1 and node2 go out of scope here...
}
Это не будет работать, потому что оно ссылается на локальные переменные функции, которые выходят из области видимости, когда функция возвращается. Версия, использующая Box
, будет работать, потому что Box
становится владельцем данных.