#rust
Написал функцию: fn read_str<'a>() -> &'a str { let mut input = String::new(); io::stdin().read_line(&mut input).ok(); let output : &str = &input[..]; &output } При компиляции возникает ошибка src/main.rs:13:26: 13:31 error: `input` does not live long enough src/main.rs:13 let output : &str = &input[..]; ^~~~~ src/main.rs:10:30: 15:2 note: reference must be valid for the lifetime 'a as defined on the block at 10:29... src/main.rs:10 fn read_str<'a>() -> &'a str { src/main.rs:11 let mut input = String::new(); src/main.rs:12 io::stdin().read_line(&mut input).ok(); src/main.rs:13 let output : &str = &input[..]; src/main.rs:14 &output src/main.rs:15 } src/main.rs:11:32: 15:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 11:31 src/main.rs:11 let mut input = String::new(); src/main.rs:12 io::stdin().read_line(&mut input).ok(); src/main.rs:13 let output : &str = &input[..]; src/main.rs:14 &output src/main.rs:15 } Пробовал брать строку io::stdin().read_line(&mut input).ok(); в фигурные скобки, дабы ограничить &mut, но это не помогает.
Ответы
Ответ 1
Вернуть из функции можно только ссылку на статический объект (с временем жизни 'static) или ссылку, которую вы получили во входных параметрах. Вы пытаетесь вернуть ссылку на объект созданный в стеке функции. После завершения функции все объекты в стеке будут уничтожены. Rust не позволит создать ссылку на объект, который она может пережить. Использование после освобождения (use after free) В вашем случае лучше всего вернуть String. Накладные расходы в этом случае невелики, так как почти вся информация внутри строки хранится в куче. Большинство проблем начинающих писать на Rust связаны с непониманием назначения различных типов указателей. Если не вдаваться в подробности, их там можно насчитать пять штук. Ссылки в Rust используются для передачи данных без передачи права владения. Например если у вас есть структура, в которой хранится строка: struct Person{ name:String } то выдавать информацию о ее содержимом лучше так: impl Person{ pub fn get_name(&self)->&str{ &self.name } } или можно вернуть копию строки: pub fn get_name_clone(&self)->String{ self.name.clone() } Но это приведет к дополнительным расходам на копирование строки. Расходы здесь возникают именно из-за копирования - вызова метода clone(), который создает вторую копию данных строки в куче, а не из-за того, что функция возвращает строку. Можно вернуть строку из структуры без копирования: pub fn get_name_own(self)->String{ self.name } Но после вызова этого метода исходный объект Person перестанет существовать, так как право владения было передано. Еще одна распространенная причина проблем - попытка хранить ссылки на другие объекты в структуре. Ссылки накладывают кучу ограничений на время жизни и мутабельность связанных объектов. Прежде чем это делать, стоит дважды подумать о возможности использования других типов указателей.
Комментариев нет:
Отправить комментарий