Ответ 1
Посмотрим на подпись для into_bytes
:
fn into_bytes(self) -> Vec<u8>
Это принимает self
, а не ссылку на self (&self
). Это означает, что self
будет потребляться и не будет доступен после вызова. Вместо него вы получаете Vec<u8>
. Префикс into_
является распространенным способом обозначения таких методов.
Я не знаю точно, что возвращает ваш метод iter()
, но я предполагаю, что он итератор поверх &String
, то есть возвращает ссылки на String
, но не дает вам права собственности на них, Это означает, что вы не можете вызвать метод, который потребляет значение.
Как вы нашли, одним из решений является использование clone
. Это создает дублирующий объект, который у вас есть, и может вызывать into_bytes
on. Как отмечают другие комментаторы, вы также можете использовать as_bytes
, который принимает &self
, поэтому он будет работать на заемное значение. Какой из них вы должны использовать, зависит от вашей конечной цели за то, что вы делаете с указателем.
В большей картине это все связано с понятием собственности. Определенные операции зависят от владения предметом, а другие операции могут уйти с заимствованием объекта (возможно, изменчиво). Ссылка (&foo
) не предоставляет права собственности, это просто заем.
Почему интересно использовать
self
вместо&self
в аргументах функции?
Передача собственности - полезная концепция в целом - когда я закончил с чем-то, у кого-то может быть это. В Русте это способ быть более эффективным. Я могу избежать выделения копии, предоставив вам одну копию, а затем выбросив мою копию. Собственность также является наиболее разрешительным государством; если у меня есть объект, который я могу сделать с ним, как пожелаю.
Здесь код, который я создал для тестирования:
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() {}