4 ms·
Works for me: #[derive(Debug)] struct Input<'a>{ words: Vec<&'a str>, phrase: &'a str, } fn main() { let s="foo bar baz"; let inpu
by drran 5y ago
Works for me:
#[derive(Debug)]
struct Input<'a>{
words: Vec<&'a str>,
phrase: &'a str,
}
fn main() {
let s="foo bar baz";
let input = Input {
words: s.split_whitespace().collect(),
phrase: s,
};
dbg!(input);
}
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.15s
Running `target/debug/playground`
[src/main.rs:13] input = Input {
words: [
"foo",
"bar",
"baz",
],
phrase: "foo bar baz",
}
- ptato 5y agoWouldn't a Box<&'a str> put the reference itself, not the contents, in the heap?
- mplanchard 5y agoInput 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)); }