Как создать срез из одного элемента, не копируя этот элемент? - PullRequest
2 голосов
/ 26 апреля 2019

У меня действительно большая структура (в куче и в стеке), которую я использую в функции.Большую часть времени я хочу простую переменную этой структуры, потому что я делаю вещи с большой структурой напрямую.В какой-то момент, однако, я вынужден (с помощью сигнатуры функции) передать эту структуру внутри среза.

struct VeryBig(Vec<String>, [u64; 50]);

fn takes_slice(_: &[VeryBig]) {}

fn main() {
    let foo = VeryBig(vec!["Ferris".to_string(); 100], [27; 50]);

    // Use `foo` directly a bunch of times

    takes_slice(&foo); // <-- mismatched type

    // Use `foo` directly a bunch of times
}

Это очевидно и понятно приводит к этой ошибке:

error[E0308]: mismatched types
  --> src/main.rs:10:17
   |
10 |     takes_slice(&foo); // <-- mismatched type
   |                 ^^^^ expected slice, found struct `VeryBig`
   |
   = note: expected type `&[VeryBig]`
              found type `&VeryBig`

Так что мне интересно: как лучше это решить?Я мог бы просто сделать foo [VeryBig; 1], но это означало бы, что я должен использовать foo[0] везде, где я хочу использовать большую структуру напрямую - раздражает.В качестве альтернативы, я мог бы временно поместить большую структуру в массив, вызвать takes_slice и снова переместить ее из массива.Но это тоже не очень хорошо.

Насколько я знаю, &T и &[T] должны иметь одинаковую структуру памяти (указатель, а не указатель), поэтому я ожидаю, что найдется способлегко интерпретировать одно как другое, но я не нашел такой возможности.

1 Ответ

2 голосов
/ 26 апреля 2019

Вы можете использовать slice::from_ref.

fn from_ref<T>(s: &T) -> &[T]

В вашем коде ( Детская площадка ):

use std::slice;

takes_slice(slice::from_ref(&foo));

Для изменяемых фрагментов вы можете использовать slice::from_mut. Также см. этот вопрос по этой теме.

...