Всем привет,
С удивлением узнал что у указателей бывает что-то вроде лафтаймов. Раньше я думал что стоит только только попросить у бокса указатель, например через Box::into_raw(boxed)
как дальше можно делать с этим указателем что угодно, хоть отправить на луну и оттуда считать его лазером, главное чтобы когда ты решил этот указатель разыменовать или превратить обратно в коробочку через Box::from_raw(ptr)
тебе надо поставить ключевое слово unsafe
и далее все на твоей совести.
Здесь я правда имею в виду trait objects. Вот мой код который не компилируется:
trait Foo {}
struct Bar<'a> { name: &'a str }
impl<'a> Foo for Bar<'a> {}
fn get_ptr<'a>(name: &'a str) -> *mut dyn Foo { // <-- указатель захотел?
let boxed = Box::new ( Bar { name } );
Box::leak(boxed) // <-- а вот и нет
}
fn main() {
let owned = "John".to_string();
let ptr = get_ptr(&owned);
println!("Hello {:?}", ptr);
}
Вот что я получаю:
error[E0759]: cannot infer an appropriate lifetime
--> src/main.rs:8:28
|
7 | fn get_ptr<'a>(name: &'a str) -> *mut dyn Foo {
| ------- this data with lifetime `'a`...
8 | let boxed = Box::new ( Bar { name } );
| ^^^ ---- ...is captured here...
9 | Box::leak(boxed)
| ---------------- ...and is required to live as long as `'static` here
|
help: to declare that the trait object captures data from argument `name`, you can add an explicit `'a` lifetime bound
|
7 | fn get_ptr<'a>(name: &'a str) -> *mut dyn Foo + 'a {
| ^^^^
error: aborting due to previous error
Чтобы этот код скомпилировался мне нужно указать лайтайм того что скрывается за указателем:
fn get_ptr<'a>(name: &'a str) -> *mut (dyn Foo + 'a) {
Такой подставы я не ожидал. Получается мне нужно как-то синтаксически доказывать компилятору что мой указатель не переживет тех ссылок которые есть у объекта на который он ссылается, что в моем случае затруднительно (если бы я мог, я бы не стал париться с указателями).
Может кто-то знает где можно про почитать про такое?
Как быть если нужен старый добрый указатель без borrowchk? Что-то вроде transmute *mut (dyn Foo + 'a)
в *mut (dyn Foo + 'static)
?