В чем разница между Vec <i32> и Vec <Box <i32>>?

let vec1 = vec![1, 2, 3, 4];
let vec2 = vec![Box::new(1), Box::new(2), Box::new(3), Box::new(4)];

В чем разница между ними? Я уже выделил vec1 в кучу. Значит, не все элементы vec1 также находятся в куче? Зачем мне нужно отдельно выделять их в куче, как в vec2?

Ответ 1

Я рисую диаграмму. Первое значение является указателем на непрерывный массив чисел в куче.

(stack)    (heap)
┌──────┐   ┌───┐
│ vec1 │──→│ 1 │
└──────┘   ├───┤
           │ 2 │
           ├───┤
           │ 3 │
           ├───┤
           │ 4 │
           └───┘

Вторая версия добавляет дополнительную косвенность. Элементы все еще находятся в куче, но теперь они находятся где-то еще в куче.

(stack)    (heap)   ┌───┐
┌──────┐   ┌───┐ ┌─→│ 1 │
│ vec2 │──→│   │─┘  └───┘
└──────┘   ├───┤    ┌───┐
           │   │───→│ 2 │
           ├───┤    └───┘
           │   │─┐  ┌───┐
           ├───┤ └─→│ 3 │
           │   │─┐  └───┘
           └───┘ │  ┌───┐
                 └─→│ 4 │
                    └───┘

Из-за того, как собственность работает в Rust, вы не столкнетесь с семантическими различиями. Дополнительная косвенность дает вам худшее использование памяти и локальность кэша.

Ответ 2

vec![1, 2, 3, 4] является вектором i32 s.

vec![Box::new(1), Box::new(2), Box::new(3), Box::new(4)] - вектор принадлежащих указателям на i32 s. Rust, принадлежащий указателю, похож на С++ unique_ptr.