Когда вы определяете черту, определение должно иметь смысл для всех возможных реализаций.
Проблема может быть не сразу ясна без примера, где она терпит неудачу. Предположим, у вас был такой тип:
struct MyStruct;
impl MyStruct {
const fn new() -> Self {
MyStruct
}
}
И вы попытались реализовать эту черту следующим образом:
impl Test for MyStruct {
const CONST: Self = MyStruct::new();
}
Это не сработает, потому что реализация static_ref
теперь будет выглядеть так:
fn static_ref() -> &'static Self {
// &Self::CONST
&MyStruct::new()
}
Это создает значение внутри функции и пытается вернуть его. Это значение не статическое, поэтому время жизни 'static
недопустимо.
Однако, немного перенастроив, вы можете заставить что-то работать:
pub trait Test: Sized + 'static {
// This is now a reference instead of a value:
const CONST: &'static Self;
fn static_ref() -> &'static Self {
Self::CONST
}
}
struct MyStruct;
impl MyStruct {
const fn new() -> Self {
MyStruct
}
}
impl Test for MyStruct {
const CONST: &'static Self = &MyStruct::new();
}
Это работает, потому что CONST
уже является ссылкой 'static
, поэтому функция может просто вернуть ее. Все возможные реализации должны иметь возможность получить 'static
ссылку на Self
для реализации черты, поэтому больше не возникает проблема со ссылкой на какое-то произвольное локальное значение.