2022/11/28
Я вернулся после более чем 2 недель молчания. Я готовился к промежуточным экзаменам, которые я полностью испортил, общался и хорошо отдыхал. Теперь я снова готов к драке.
Сегодня я буду следовать этому уроку.
use std::io;
Это выглядит достаточно просто. Мы вносим библиотеку «io (ввод-вывод)», которая исходит из библиотеки «std». Для каждой программы Rust Rust автоматически добавляет библиотеки, автоматически называемые «prelude». Если вы хотите использовать библиотеки за пределами этой области, вы должны использовать «use».
Кстати, встраивание кода в Medium стало намного сложнее. Я люблю это!
let mut guess = String::new();
Наша первая переменная Rust!
Давайте сделаем шаг назад и поймем, как работают переменные в Rust.
let apples = 5;
Эта строка кода проста: мы объявляем переменную «яблоки» и присваиваем ей значение 5. Однако все переменные в Rust по умолчанию неизменяемы, то есть их нельзя изменить. Чтобы сделать переменную изменяемой, мы добавляем «mut».
let mut bananas = 5; //This is comment
Вы также можете вставлять комментарии в код с помощью «//».
String::new();
Эта строка кода создает экземпляр типа «String». «::» указывает, что «новая» — это связанная функция, которая является типом функции, реализованной на типе.
let mut guess = String::new();
Итак, вернемся к этой строке кода. Он создает изменяемую переменную «угадай» и присваивает ей новый экземпляр «String», который в настоящее время пуст.
io::stdin() .read_line(&mut guess)
Эта строка кода получает пользовательский ввод. Мы используем функцию stdin, которую мы импортировали из библиотеки std::io. В качестве альтернативы вы можете использовать std::io::stdin(). Функция read_line получает ввод и добавляет к строке, переданной в качестве аргумента, не перезаписывая ее, в данном случае «угадай».
«&» означает, что это ссылка. Мы используем ссылку для вызова переменной без необходимости использовать память каждый раз. Одной из главных особенностей Rust является безопасность использования ссылок. Они также неизменяемы по умолчанию, поэтому вам нужно добавить «mut».
.expect("Failed to read line");
Эта строка обрабатывает ошибку. Эта часть будет подробно рассмотрена в следующей части книги.
Вам не обязательно указывать метод «ожидание», но это рекомендуется. Компилятор Rust компилирует его за вас, но все равно показывает предупреждение.
println!("You guessed: {guess}");
Эта строка выводит ввод. Это интуитивно понятно. Он заменит «{guess}» значением «guess».
use std::io; fn main(){ println!("Please enter a number"); let mut guess = String::new(); io::stdin() .read_line(&mut guess) .expect("Could not read you input"); println!("You guessed {guess}"); }
Мы можем проверить программу. Он должен принять ввод и распечатать его обратно.
Большой!
Теперь давайте сгенерируем секретное случайное число от 1 до 100.
Крейт — это набор файлов с исходным кодом Rust. Для наших целей мы будем использовать ящик «ранд». крейт «ранд» — это библиотечный крейт, что означает, что он был написан с намерением использовать его другими файлами. Наш main.rs — это бинарный крейт, то есть исполняемый.
Чтобы использовать ящик «ранд», нам нужно изменить Cargo.toml.
В [зависимости] мы должны добавить
rand = "0.8.3"
Если сейчас ввести команду «грузовой рейс»…
Cargo загружает файлы, необходимые для зависимостей, с crates.io.
Чтобы версии зависимостей оставались одинаковыми для воспроизводимости, Cust создает для нас Cargo.lock.
Если вы хотите использовать последнюю версию зависимостей и игнорировать Cargo.lock, вы можете сделать
cargo update
Экосистема Cargo будет подробно описана далее в книге.
Теперь давайте на самом деле создадим случайное число.
use rand::Rng; fn main(){ let secret_number = rand::thread_rng().gen_range(1..=100); println!("The secrete number is {secret_number}"); }
Вы можете видеть, что программа успешно выводит случайное число в диапазоне от 1 до 100.
start..=end
Этот диапазон включает как нижнюю, так и верхнюю границы.
Теперь давайте сравним ввод пользователя с секретным номером. Способ сделать это — использовать метод «cmp». Грамматика выглядит так.
guess.cmp(&secret_number)
«cmp» сравнивает предположение со ссылкой на secret_number, сравнивает их и возвращает вариант перечисления «Ordering», который нельзя передать в println! функция.
Или, может быть, мне просто нужно поместить его внутри {}.
Очевидно нет. Я не совсем уверен, почему. Но пока давайте двигаться дальше.
Во всяком случае, сравнение выглядит так
use std::cmp::Ordering; fn main(){ let a = 5; let b = 5; match a.cmp(&b){ Ordering::Less => println!("LESS"), Ordering::Equal => println!("EQUAL"), Ordering::Greater => println!("GREATER"), } }
С помощью «match» мы можем решить, что делать с перечислением, которое возвращает «cmp». Есть только три исхода: а меньше b, а равно b или а больше b.
Каждый «Порядок» в этом коде называется «руками» «совпадения».
Для последнего шага сравнения мы должны преобразовать пользовательский ввод в число, поскольку, как и в python, типы int и строковые типы не могут сравниваться без преобразования.
let guess: u32 = guess.trim().parse().expect("Please type a number!");
Давайте разберем этот код.
У нас уже есть переменная «угадай», и мы хотим преобразовать ее в целочисленное значение, u32, сокращение для «неназначенного 32-битного целого числа», в данном случае.
trim() считывает все пробелы и символы синтаксического анализа в начале и в конце символа. Например, когда пользователь вводит 5, Rust видит это как «5\n». trim() избавляется от части «\n», которая необходима для преобразования «догадки» в целое число.
parse() изменяет переменную на другой тип.
Проверим, работает ли код.
Хороший.
Теперь все, что нам нужно сделать, это реализовать цикл. Вы буквально реализуете бесконечный цикл с помощью «loop» и прерываете его с помощью «break».
use std::io; use rand::Rng; use std::cmp::Ordering; fn main(){ let secret_number = rand::thread_rng().gen_range(1..=100); loop{ let mut guess = String::new(); println!("Enter a number"); io::stdin() .read_line(&mut guess) .expect("Could not read you input"); let guess: u32 = guess.trim().parse().expect("Please enter a number"); match guess.cmp(&secret_number){ Ordering::Less => println!("UP"), Ordering::Equal => { println!("YOU WIN!"); break; }, Ordering::Greater => println!("DOWN"), } } }
Это мой код до сих пор.
И это работает отлично.
Давайте просто добавим в этот код одну деталь; обработка ошибок. Мы можем использовать «совпадение», чтобы решить, что делать при обнаружении ошибки; ввод строки вместо числа для этого случая.
let guess: u32 = match guess.trim().parse(){ Ok(num) => num, Err(_) => continue, };
«продолжить», как и в python, пропускает оставшуюся часть цикла и перезапускает цикл. Таким образом, программа будет бесконечно запрашивать число, пока пользователь не введет число.
use std::io; use rand::Rng; use std::cmp::Ordering; fn main(){ let secret_number = rand::thread_rng().gen_range(1..=100); loop{ let mut guess = String::new(); println!("Enter a number"); io::stdin() .read_line(&mut guess) .expect("Could not read you input"); let guess: u32 = match guess.trim().parse(){ Ok(num) => num, Err(_) => continue, }; match guess.cmp(&secret_number){ Ordering::Less => println!("UP"), Ordering::Equal => { println!("YOU WIN!"); break; }, Ordering::Greater => println!("DOWN"), } } }
Мой последний код.
Оно работает!
Это все на сегодня. Мне очень нравится изучать Rust, и я очень рад узнать больше и создать полезное программное обеспечение с помощью Rust. Надеюсь, я не поленюсь это сделать.