4 ms·
Input isn’t self-referential in your example, because both of its fields are referencing the same data owned by the main function. For it to be self-referentia
by mplanchard 5y ago
Input isn’t self-referential in your example, because both of its fields are referencing the same data owned by the main function.
For it to be self-referential, Input needs to take ownership of the string in phrase, and words needs to then be referencing phrase.
You can do this with Pin, but it’s not simple.
- drran 5y agoYep, it can be done with Pin and unsafe only, AFAIK. In theory, Rust can be extended to have relative references, but it's much simpler to use arrays and indexes and ranges instead. With Pin: use std::pin::Pin; use std::marker::PhantomPinned; #[derive(Debug)] struct Input<'a>{ words: Vec<&'a str>, phrase: Box<str>, _marker: PhantomPinned, } fn test<'a>(s: String) -> Pin<Box<Input <'a>>> { let bs = s.into_boxed_str(); let mut input = Box::pin( Input { phrase: bs, words: Vec::new(), _marker: PhantomPinned, }); unsafe { let phrase: *const Box<str> = &input.as_ref().phrase; let words = phrase.as_ref().unwrap().split_whitespace().collect(); input.as_mut().get_unchecked_mut().words = words; } input } fn main() { let s="foo bar baz".to_string(); dbg!(test(s)); }