Let's look at the signature for into_bytes
:
fn into_bytes(self) -> Vec<u8>
This takes self
, not a reference to self (&self
). That means that self
will be consumed and won't be available after the call. In its place, you get a Vec<u8>
. The prefix into_
is a common way of denoting methods like this.
I don't know exactly what your iter()
method returns, but my guess is that it's an iterator over &String
, that is, it returns references to a String
but doesn't give you ownership of them. That means you cannot call a method that consumes the value.
As you've found, one solution is to use clone
. This creates a duplicate object that you do own, and can call into_bytes
on. As other commenters mention, you can also use as_bytes
which takes &self
, so it will work on a borrowed value. Which one you should use depends on your end goal for what you do with the pointer.
In the larger picture, this all has to do with the notion of ownership. Certain operations depend on owning the item, and other operations can get away with borrowing the object (perhaps mutably). A reference (&foo
) does not grant ownership, it's just a borrow.
Why is it interesting to use self
instead of &self
in a function's arguments?
Transferring ownership is a useful concept in general - when I am done with something, someone else may have it. In Rust, it's a way to be more efficient. I can avoid allocating a copy, giving you one copy, then throwing away my copy. Ownership is also the most permissive state; if I own an object I can do with it as I wish.
Here's the code that I created to test with:
struct IteratorOfStringReference<'a>(&'a String);
impl<'a> Iterator for IteratorOfStringReference<'a> {
type Item = &'a String;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
struct FileLikeThing {
string: String,
}
impl FileLikeThing {
fn iter(&self) -> IteratorOfStringReference {
IteratorOfStringReference(&self.string)
}
}
struct Dummy {
xslg_file: FileLikeThing,
buffer: String,
}
impl Dummy {
fn dummy(&mut self) {
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
}
}
fn main() {}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…