Перейти к содержанию

Rust - В статике есть нечто большее, чем может показаться на первый взгляд

Posted on:1 апреля 2023 г. at 11:12

Example Dynamic OG Image link Ни для кого не секрет, что первый сценарий использования “static”, который приходит на ум, - это сценарий в сочетании со ссылкой. Скажем, &'static str . Любой человек время от времени объявлял такие переменные const в своем коде. Кроме того, крайне важно поставить этот явный апостроф с дополнительной надписью после него. Это не может быть опущено, поскольку предполагается, что константы будут существовать всё время выполнения.

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

Давайте взглянем на следующий код:

struct Service<SS: ServiceSetup> {
  ss: SS,
}

trait ServiceSetup { }

Это какой-то сервис, зависящий от универсального типа, который должен каким-то образом настраивать сервис. Довольно обычный, не так ли?

Теперь давайте представим, что мы хотим дополнить нашу программу каким-нибудь асинхронным материалом. Скажем, такие каналы, как tokio::sync::mpsc, futures::channel::mpsc или даже tokio::sync::broadcast, почему бы и нет? Вдобавок ко всему, мы бы предпочли не только открыть pipe, но и передавать в него, иначе это было бы совершенно бессмысленно.

Как вы относитесь к tokio::spawn асинхронного блока для этой задачи? Если вы согласны со мной, вы бы согласились с утверждением, что это может иметь свое применение для передачи точного типа по каналу, являющемуся частью универсального ServiceSetup.

struct Service<SS: ServiceSetup> {
  ss: SS,
}

trait ServiceSetup {
  type Message;
}

Итак, каковы предварительные условия для того, чтобы Message можно было передавать внутри асинхронного блока?

struct Servie<SS: ServiceSetup> {
  chan: broadcast::Sender<SS::Message>,
  ss: SS,
}

trait ServiceSetup {
  type Message: Send + Sync + 'static;
}

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

Неудивительно, что это должно быть отправлено синхронно, но этого недостаточно. Это должено быть независимым от области, в которой оно было создано, т.е. это может быть что-то без внешних ссылок. Как это указать? С самого начала используя 'static.

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