Каковы некоторые варианты использования структур кортежей?

#struct #rust

#Ржавчина

Вопрос:

В книге Rust упоминается, что «почти всегда лучше использовать структуру, чем структуру кортежей». Помимо шаблона newtype, есть ли какие-либо другие преимущества наличия неназванных полей? Мне кажется, что шаблон newtype — единственный полезный случай наличия структур кортежей.

Комментарии:

1. Другой вариант использования — математические векторы малой арности. Например, в библиотеке векторной обработки 2d или 3d. Хотя вы также можете использовать newtype для массива.

Ответ №1:

Они очень похожи друг на друга.

Учитывая следующие определения

 struct TupleStruct(i32, i32);
struct NormalStruct {
    a: i32,
    b: i32,
}
 

мы можем создавать экземпляры структур и структур кортежей следующим образом

 let ts = TupleStruct(1, 2);
let ns = NormalStruct { a: 1, b: 2 };

// shortcut to initialize the fields of a struct using the values of the
// fields of another struct
let ns2 = NormalStruct { a: 5, ..ns };
let ts2 = TupleStruct { 0: 1, ..ts }; // for TupleStruct it needs curly brackets
                                      // and implicit field names
 

Назначения работают следующим образом

 let TupleStruct(x, y) = ts;
println!("x: {}, y: {}", x, y);

let NormalStruct { a, b } = ns;
println!("a: {}, b: {}", a, b);
 

Поля структуры кортежа имеют неявные имена (0, 1, …). Следовательно, доступ к полям выполняется следующим образом

 println!("Accessing ns by name - {}{}", ns.a, ns.b);
println!("accessing ts by name - {}{}", ts.0, ts.1);
 

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

Однако могут быть случаи, когда поля структуры по своей сути являются «анонимными», одним из примечательных случаев является «newtype» (структура кортежа с одним полем), где вы оборачиваете только внутренний тип.

В этом случае присвоение имени внутреннему полю, возможно, не предоставляет никакой дополнительной информации.

 struct Inches {
    inner: i32,
}
 

против

 struct Inches(i32);
 

Раздел о структурах в книге Rust содержит больше информации о новых типах.

Комментарии:

1. Спасибо. Какое предпочтение отдается type Args = (i32, i32) vs struct Args(i32, i32) . ?

2. @HelinWang это две разные вещи. С type помощью вы определяете псевдоним (вы создаете другое имя для одного и того же объекта), и вы можете использовать его в любом месте, где вы использовали бы другое. См. playground

3. Есть ли какая-либо существенная разница в использовании и распределении памяти, помимо хранения имен полей? Или это просто два разных способа реализации одного и того же?