How to design a struct when I need to reference to

2019-02-18 04:49发布

问题:

My previous question tells me that rust cannot take reference to itself in a struct.

using self in new constructor

So my question would become: how to design a struct when I need to reference to itself?

We might take this struct as an example:

struct SplitByChars<'a> {
    seperator: &'a Seperator,
    string: String,
    chars_iter: std::str::Chars<'a>,
}

impl<'a> SplitByChars<'a> {
    fn new<S>(seperator: &'a Seperator, string: S) -> SplitByChars where S: Into<String> {
        SplitByChars {
            seperator: seperator,
            string: string.into(),
            chars_iter: self.string.chars(), // error here: I cannot use self (of course, static method)
        }
    }
}

I used chars_iter to provide an interface of iterable string splitting.

(This is just an example, so I'd like to know about a more general idea on designing the struct, not specially in this splitting case. Moreover, no std's split.)

Thx in advance!

回答1:

You can’t. Rust’s iterators are not designed to be used that way. Rearrange things so that you don’t need to store the string inside the iterator. It should only have a reference.



回答2:

While a field cannot reference another field within a struct, you can usually achieve what you need by moving them. It works by having one field as data and another field as an Option containing some struct taking that data by value (and implementing some trait of your interest).

You can find the example in this answer implementing an itetaror adaptor, where the data was a HashMap and the Option contained the map's IntoIter. During the iteration once the access to the map was no longer needed, it was moved into IntoIter using std::mem::replace.

However, in your specific case there is no method in std that would create Chars iterator by consuming the String (i.e. using self as an argument). You would have to implement it yourself.



标签: rust