//вот мой код. Это преобразователь температуры, который принимает входные данные для Кельвина, Цельсия или Фаренгейта и выводит преобразованное значение для соответствующих противоположных единиц.
// Проблема:
// сначала будет запрашиваться значение, которое должно быть числом, поэтому цикл перезапускается. хорошо // затем он запросит единицу измерения, которая должна быть k,c или f. При другой записи он улавливает и печатает «введите k для кельвинов, c для градусов Цельсия, F для градусов Фаренгейта». // Но ввод не регистрируется и переходит к началу цикла, запрашивая значение в числах.
// В общем, я хочу поймать единичную переменную с помощью k, c или f, иначе попросите пользователя сделать это, а не переходить к началу цикла.
// я изучаю ржавчину, так что извините меня за что-то нестандартное.
//Вот мой main.rs:
fn main() {
println!("\nWelcome. This is Temperature-Converter\n");
println!("I work with Fahrenheit, Celsius and Kelvin");
println!("\nPlease Input the Value you want to convert: ");
loop{
let mut value = String::new();
std::io::stdin().read_line(&mut value).expect("Failed to read line");
let value:f32 = match value.trim().parse(){
Ok(num) => num,
Err(_) => {
println!("please input value in number(s).");
continue;
}
};
println!("Thank You, I have the value: {value}.\nPlease provide it's respective unit of measurement.");
println!("K : for Kelvin C : for Celsius F : for Fahrenheit : ");
let mut unit = String::new();
std::io::stdin().read_line(&mut unit).expect("Failed to read line");
let unit = unit.trim().to_uppercase();
let unit = match unit.as_str() {
"K"=>"K",
"F"=>"F",
"C"=>"C",
_=>{
println!("please input K, F or C for Kelvin, Fahrenheit or Celcius respectively.");
continue;
}
};
println!("Thank you for your input. I see that you want to convert {value} degree {unit}.");
println!("Please wait while i provide all possible conversions.\nThis will be quick.");
if unit == "K"{
let value_c = value-273.15;
let value_f = (((value-273.15)*9.0)+(32.0*5.0))/5.0;
println!("{value}{unit} is converted to: {value_c}C and {value_f}F");
println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!");
break;
}
else if unit == "C"{
let value_k = value+273.15;
let value_f = (value*(9.0/5.0))+32.0;
println!("{value}{unit} is converted to:{value_k}K and {value_f}F");
println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!");
break;
}
else if unit == "F"{
let value_k = (((value-32.0)*5.0)/9.0)+273.15;
let value_c = ((value-32.0)*5.0)/9.0;
println!("{value}{unit} is Converted to: {value_k}K and {value_c}C");
println!("Thank You for using Temperature-Converter. It was a pleasure to assist you. Byee!!");
break;
};
}
}
//Я пытался :
if let unit = match unit.as_str() {
"K"=>"K",
"F"=>"F",
"C"=>"C",
_=>{println!("please input K, F or C for Kelvin, Fahrenheit or Celcius respectively.")}
};
// На самом деле мне трудно понять "совпадение", область действия и возвращаемое значение "цикла"
Вы также можете использовать свой начальный match на экране, добавив ветку _ => { ...error handler... }.
да. когда я использую совпадение с variabe типа String, мне пришлось преобразовать тип String в тип &str с помощью .as_str(), но когда я пытаюсь использовать то же выражение совпадения с выражением if let, выдает ошибку, говорящую, что ожидаемая &str получила строку.
Это правда, вы не можете сопоставить напрямую на String, но вы можете на &str через as_str(). Вы делаете это уже с кодом предупреждения вашего устройства. Я говорю, что вы можете расширить это вместо цепочки if.
извините, мой код очень компактный и его трудно читать. попробую отредактировать. и учтите это в следующий раз. Да, я попробовал обработчик ошибок, и он его ловит. там нет проблем. просто после уведомления об ошибке std::io возвращается к началу цикла. Я пытаюсь связать это совпадение внутри цикла/если как-то так, чтобы, когда я выхожу из него, я мог нацелить вложенный цикл на «цель», а не начинать с начала, а также получить значение из согласованного оператора. извините, если это не имеет смысла .. спасибо за попытку
Большая часть проблем при чтении кода возникает из-за того, что он очень плотный, и в каждой отдельной строке происходит много всего. Подумайте о том, чтобы лучше расставлять интервалы, например x - y вместо x-y. Вы также можете опустить такие вещи, как :f32, если тип тривиально получен из вычислений, поскольку, например, value уже имеет правильный тип.
Один из способов упростить выход из цикла — использовать функции, чтобы упростить управление потоком управления. Можно просто return.
Rust имеет тенденцию ориентироваться на такие шаблоны, как «сохранять недопустимые состояния непредставимыми», то есть иметь enum TemperatureUnit, к которым вы можете добавить много функций. Точно так же сделайте struct Temperature { unit: TemperatureUnit, value: f32 } для обозначения температуры. Разбейте этот монолитный код на более мелкие и легко тестируемые части. То, что у вас есть, можно протестировать только как гигантский кусок кода, вы не можете проверить, что, скажем, конкретная строка работает правильно. Если бы эта строка была в функции, это было бы тривиально для #[test].

Логику программы еще можно упростить, пока здесь решаются только синтаксические проблемы:
fn main() {
println!("\nWelcome. This is Temperature-Converter\n");
println!("I work with Fahrenheit, Celsius and Kelvin");
println!("\nPlease Input the Value you want to convert: ");
loop {
let mut input = String::new();
let mut value = 0.0_f32;
match std::io::stdin().read_line(&mut input) {
Ok(_) => {
value = match input.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("please input value in number(s).");
continue;
}
};
println!("Thank You, I have the value: {value}.");
}
Err(_) => println!("Failed to read line"),
}
println!("Please provide it's respective unit of measurement.");
println!("K: for Kelvin C: for Celsius F: for Fahrenheit : ");
let mut unit;
loop {
unit = String::new();
match std::io::stdin().read_line(&mut unit) {
Ok(_) => {
unit = unit.trim().to_uppercase();
match unit.as_str() {
"K" | "F" | "C" => break,
_ => println!("please input K, F or C for Kelvin, Fahrenheit or Celcius respectively."),
}
}
Err(_) => println!("Failed to read line"),
}
}
println!("Thank you for your input. I see that you want to convert {value} degree {unit}.");
println!("Please wait while i provide all possible conversions.\nThis will be quick.");
if unit == "K" {
let value_c = value - 273.15;
let value_f = (((value - 273.15) * 9.0) + (32.0 * 5.0)) / 5.0;
println!("{value}{unit} is converted to: {value_c}C and {value_f}F");
println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!");
break;
} else if unit == "C" {
let value_k = value + 273.15;
let value_f = (value * (9.0 / 5.0)) + 32.0;
println!("{value}{unit} is converted to:{value_k}K and {value_f}F");
println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!");
break;
} else if unit == "F" {
let value_k = (((value - 32.0) * 5.0) / 9.0) + 273.15;
let value_c = ((value - 32.0) * 5.0) / 9.0;
println!("{value}{unit} is Converted to: {value_k}K and {value_c}C");
println!("Thank You for using Temperature-Converter. It was a pleasure to assist you. Byee!!");
break;
};
}
}
спасибо за вашу большую помощь. многому научился, как получить значение, не соответствующее совпадению, в случае целого числа, числа с плавающей запятой и строки. как вы сказали, я дополнительно внес синтаксическую корректировку. например, поместить цикл в оператор let. большое спасибо.
Спасибо пользователю: Kaplan я только что определил переменные с помощью цикла, а затем разорвал цикл со значением переменной из цикла.
fn main() {
println!("\nWelcome. This is Temperature-Converter\n");
println!("I work with Fahrenheit, Celsius and Kelvin");
println!("\nPlease Input the Value you want to convert: ");
let value:f32 = loop{
let mut value = String::new();
std::io::stdin()
.read_line(&mut value)
.expect("Failed to read line");
match value.trim().parse::<f32>(){
Ok(num) => break num,
Err(_) => {
println!("please input value in number(s).");}
};
};
println!("Thank You, I have the value: {value}.\nPlease provide it's respective unit of measurement.");
println!("K : for Kelvin C : for Celsius F : for Fahrenheit : ");
let unit = loop{
let mut unit = String::new();
std::io::stdin()
.read_line(&mut unit)
.expect("Failed to read line");
let unit = unit.trim().to_uppercase();
match &*unit{
"K" | "F" | "C" => break unit,
_=>{
println!("Please input K, F or C for Kelvin, Fahrenheit or Celsius respectively.\nI am not case sensitive.");
}
};
};
if unit == "K"{
let value_c = value-273.15;
let value_f = (((value-273.15)*9.0)+(32.0*5.0))/5.0;
println!("{value}{unit} is converted to: {value_c}C and {value_f}F");
println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!");
}
else if unit == "C"{
let value_k = value+273.15;
let value_f = (value*(9.0/5.0))+32.0;
println!("{value}{unit} is converted to:{value_k}K and {value_f}F");
println!("Thank You for using Temperature Conversior. It was a pleasure to assist you. Byee!!");
}
else if unit == "F"{
let value_k = (((value-32.0)*5.0)/9.0)+273.15;
let value_c = ((value-32.0)*5.0)/9.0;
println!("{value}{unit} is Converted to: {value_k}K and {value_c}C");
println!("Thank You for using Temperature-Converter. It was a pleasure to assist you. Byee!!");
};
}
Изучать Rust — это здорово, но здесь вам нужно более подробно объяснить техническую проблему. Вы не знаете, как преобразовать цепочку
ifвmatch?