2016-08-10 2 views
0

Что хороший способ для заполнения вектора в Русте структур, где:Как выполнить эффективную инициализацию вектора в Rust?

  • Размер является динамичным, но известно, что во время инициализации.
  • Не инициализирует память сначала фиктивным значением.
  • Не перераспределяет память как заполненную.
  • В этом примере все элементы вектора всегда инициализирован.
    (В соответствии с гарантией Rusts без какого-либо неопределенного поведения).

А в идеале

  • ли не индексировать проверять каждый доступ индекса
    (так как размер известен при объявлении вектора это должно быть возможно).
  • Не требует unsafe
    (Не уверен, что это разумно, однако компилятор _could_ обнаружил, что все значения всегда заполнены, что позволяет использовать такую ​​логику в небезопасном блоке).

: C эквивалент:

struct MyStruct *create_mystruct(const uint n) { 
    struct MyStruct *vector = malloc(sizeof(*vector) * n); 
    for (uint i = 0; i < n; i++) { 
     /* any kind of initialization */ 
     initialize_mystruct(&vector[i], i); 
    } 
    return vector; 
} 

Я портировании над некоторыми C код, который заполняет массив в простом цикле, так что мне было интересно, если там был Сельский способ выполнения такая общая задача с нулевыми или, по крайней мере, минимальными накладными расходами?

Если для версии Rust этого кода обычно требуются дополнительные проверки, какой ближайший эквивалент?

+0

См. Также http://stackoverflow.com/q/20734743/155423, http://stackoverflow.com/q/27062874/155423, http://stackoverflow.com/q/27393166/155423, http://stackoverflow.com/q/28656387/155423, http://stackoverflow.com/q/29530011/155423, http://stackoverflow.com/q/31360993/155423. – Shepmaster

+0

Проверяли все остальные вопросы, не думайте, что они прямые дубликаты (хотя некоторые из них близки). – ideasman42

ответ

5

Просто используйте map и collect.

struct MyStruct(usize); 

fn create_mystructs(n: usize) -> Vec<MyStruct> { 
    (0..n).map(MyStruct).collect() 
} 

«Инициализация» не имеет смысла в безопасном Руст, потому что вы должны иметь возможность доступа к неинициализированным значения, что является небезопасным. Метод Iterator::size_hint может использоваться при сборе в контейнер для обеспечения минимального количества распределений.

В принципе, я был бы уверен, что оптимизатор пойдет правильно. Если это не так, я бы поверила, что в конечном итоге это произойдет.

+0

Как будет выглядеть 'initialize_mystruct'? Кроме того, я полагаю, что Rust достаточно умен, чтобы обнаружить, что итератор имеет фиксированный размер и не изменяет размер вектора при запуске? – ideasman42

+1

@ ideasman42 Вы должны использовать конструктор 'MyStruct' вместо' initialize_mystruct', а затем сделать '.map (MyStruct :: new)'. Руст знает, что «карта» сохраняет длину и будет правильно распределяться, да. – Veedrac

+0

И поскольку я использовал * tuple struct *, конструктор 'MyStruct' - это просто' MyStruct', функция, вызываемая в 'map'. – Shepmaster

 Смежные вопросы

  • Нет связанных вопросов^_^