Refering to own members while constructing an object

Hi I have a struct that contains a String data and a view of that raw data. To minimize copying I opted for this design. Problem is, however, that I cannot seem to construct the view by referring to the previously assigned member.

pub struct MyType <'x> { 
    raw_data: String,
    pub view: &'x str

impl <'x> MyType <'x> {
    pub fn construct(arg: String) -> Self {
        MyType {
            raw_data: arg,
            view: &raw_data[1 .. ] // E: a field by this name exists in `Self`

fn main() {
    let my_obj = MyType::construct(String::from("ABCDEFGH"));
    println!("{}", my_obj.view);

Obviously, the BC would prevent me from refegring to &arg[1..] instead. What should I do?

Remember that

  1. The arg is a big (upto 10k chars) string, and evaluation of arg is very expensive (takes upto 1 second in my decent system). Which is why I'm trying to reduce latency as much as I can wherever possible.
  2. The view is just a small example, in the codebase, the view is actually structs containing more structs but they all internally have &strs that refer to the big raw_data String's different substrings.

Seperate raw and view into different types. You are trying to create a self referential type, and you can't do anything useful with those unless you use some tricky unsafe code.

Instead you can have 1 type to store the expensive calculations and many others that are simply views into the first.


When doing this

OP can still hold the values in the same struct right?
Something like this

pub struct Wrapper<'a>(&'a str);

impl<'a> std::ops::Deref for Wrapper<'a> {
    type Target = &'a str;
    fn deref(&self) -> &Self::Target {

pub struct MyType <'x> { 
    raw_data: String,
    pub view: Wrapper<'x>

impl <'x> MyType <'x> {
    // Note that String is now &str, it needs a lifetime to compile
    pub fn construct(arg: &'x str) -> Self {
        let view = Wrapper(&arg);
        MyType {
            // my example may not be great because of this
            raw_data: arg.to_owned(),


But now you no longer have a view into raw_data, and uou are copying stuff. This is counter productive, you may as well just have &str and not String in MyType.

What about something like is there any reason this wouldn't work?

// the different types could be returned from different methods?
pub fn view(&self) -> &str {

Or are there costs to this I'm not seeing?

1 Like

That would also work, the only costs is the indexing on every use, but that should be fine in the grand scheme of things.

1 Like

One thing to note is that you can have and use a self-referential type under certain circumstances:

  • We construct and assign the self-reference after having run the constructor for the type (I mean the declarative struct syntax such as MyType { data: my_string, view: None }).
  • We cannot move this type afterwards, but can use it as normal in the same scope.

We can declare a type:

struct MyType<'a>(String, Option<&'a str>);

let mut x = MyType(String::new(), None); //'a is indeterminate currently
x.1 = Some(&x.0); //We've assigned x.1 a value with x's lifetime
//Therefore if we could name x's lifetime, its type would be
// MyType<'x>
//Hence it borrows from itself for the remainder of its lifetime.
//We can only run `&self` methods though, because we could do something 
//like so in an `&mut self` method:
x.1 = String::from("abc");
println!("{}", x.0); // Garbage

Although, if we did something like the following:

struct MyType<'a>(String, Option<&'a mut str>);

let mut x = MyType(String::new(), None);
x.1 = Some(&mut x.0);

We wouldn't be able to do anything with x because it now borrows from itself mutably, meaning we can't even run &self methods like before!