Этот список может быть не исчерпывающим, но во многих случаях целесообразно не брать аргументы.
1.Эффективность с небольшими Copy
типами
Если тип маленький и реализует Copy
, обычно более эффективно копировать его, чем передавать указатели.Ссылки означают косвенность - помимо необходимости выполнять два шага для получения данных, значения за указателями с меньшей вероятностью будут компактно храниться в памяти и, следовательно, медленнее копировать в кэши ЦП, например, если вы выполняете итерации по ним.
2.Передача права собственности
Если вам нужно, чтобы данные оставались в памяти, но текущего владельца нужно было очистить и выйти из области видимости, вы можете передать право собственности, переместив их в другое место.Например, вы можете иметь локальную переменную в функции, но переместите ее в Box
, чтобы она могла жить после того, как функция вернулась.
3.Цепочка методов
Если набор методов все потребляют self
и возвращают Self
, вы можете удобно объединить их в цепочку, не требуя промежуточных локальных переменных.Вы часто будете видеть этот подход, используемый для реализации сборщиков.Вот пример, взятый из документации derive_builder
crate :
let ch = ChannelBuilder::default()
.special_info(42u8)
.token(19124)
.build()
.unwrap();
4.Статическое применение инвариантов
Иногда требуется, чтобы значение использовалось функцией для гарантии того, что оно не может быть использовано снова, как способ применения допущений на уровне типа.Например, в futures
ящике метод Future::wait
потребляет self
:
fn wait(self) -> Result<Self::Item, Self::Error>
where
Self: Sized,
Эта подпись специально разработана для предотвращения повторного вызова wait
.Реализация не должна проверять во время выполнения, чтобы увидеть, находится ли будущее уже в состоянии ожидания - компилятор просто не допустит такой ситуации.
Она также обеспечивает защиту от ошибок при использовании построенных по методам компоновщиков,Конструкция статически не позволяет вам делать вещи не по порядку - вы не можете случайно установить поле на построителе после того, как объект создан, потому что построитель используется его методом build
.
5.Чтобы сделать клонирование явным для вызывающих абонентов
Некоторые функции должны владеть своими данными.Это может быть применено путем принятия ссылки и последующего вызова clone
внутри функции, но это не всегда может быть идеальным, потому что это скрывает потенциально дорогостоящую операцию клонирования от вызывающей стороны.Принятие значения вместо ссылки означает, что вызывающий объект может клонировать значение или, если он им больше не нужен, переместить его.