Я пытаюсь получить String
со стандартного ввода:
use std::io;
fn ask_nick() -> String {
let reader = io::stdin();
let mut buffer: String = String::new();
let nickname: String = reader.read_line(&mut buffer).ok()
.expect("ERRMSG").to_string();
println!("OK: Hello {}!", &nickname);
return nickname;
}
}
fn main() {
let nickname: String = ask_nick();
println!("{}", nickname);
}
Но преобразование из usize
в String
, похоже, изменяет содержимое до его длины:
INPUT:= John
EXPECTED OUTPUT:= OK: Hello John!
John
OUTPUT:= OK: Hello 5!
5
INPUT:= Doe
EXPECTED OUTPUT:= OK: Hello Doe!
Doe
OUTPUT:= OK: Hello 4!
4
@TimDiekmann Я редактировал содержание вопроса. Как мне преобразовать reader.read_line (& mut buffer), который является usize, в строку, не изменяя ее содержимое на длину его содержимого?
Лучший способ конвертировать usize
в String
- через to_string
, точно так же, как вы это делаете. Какой у вас вопрос настоящий?
@Shepmaster Проблема заключается в путанице по поводу того, как работает read_line
. OP ожидает, что функция вернет строку, но фактически возвращает количество прочитанных байтов и изменяет предоставленный буфер.
Пожалуйста, посмотрите документация, и вы можете увидеть, что read_line
мутирует - содержимое своего параметра (в вашем случае, пустая строка, привязанная к buffer
), помещает в него прочитанное значение и возвращает длина читать. Но вы разворачиваете этот результат и конвертируете эту длину в строку.
Вместо этого ваша функция должна выглядеть так:
fn ask_nick() -> String {
let reader = io::stdin();
let mut buffer: String = String::new();
reader.read_line(&mut buffer)
.ok()
.expect("ERRMSG");
println!("OK: Hello {}!", buffer);
return buffer;
}
Или, что еще более идиоматично, не паниковать, когда предоставляется недопустимый ввод:
fn ask_nick() -> Result<String> {
let reader = io::stdin();
let mut buffer: String = String::new();
match reader.read_line(&mut buffer) {
Ok(_) => Ok(buffer),
Err(e) => Err(e),
}
}
В этом варианте вызывающий - тот, кто решает, как обрабатывать ошибки.
Если не считать неправильного использования переменной nickname
после ее удаления (в вашем первом фрагменте), это правильно. Вам также не нужно передавать их по ссылке на макрос println
, так как он все равно не станет владельцем.
@SimonWhitehead хороший улов! я на самом деле мысленно проигнорировал эту строчку случайно.
Я думаю, вы могли бы заменить это последнее совпадение на reader.read_line(&mut buffer).map(|_| buffer)
, если хотите быть по-настоящему кратким :) Если только нет каких-то странностей с семантикой закрывающих ходов, которые я не учел, то есть!
В чем именно заключается ваш вопрос? Что вы ожидаете от программы?