Как объединить выражение if let match в ржавчине

//вот мой код. Это преобразователь температуры, который принимает входные данные для Кельвина, Цельсия или Фаренгейта и выводит преобразованное значение для соответствующих противоположных единиц.

// Проблема:

// сначала будет запрашиваться значение, которое должно быть числом, поэтому цикл перезапускается. хорошо // затем он запросит единицу измерения, которая должна быть 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.")}
};

// На самом деле мне трудно понять "совпадение", область действия и возвращаемое значение "цикла"

Изучать Rust — это здорово, но здесь вам нужно более подробно объяснить техническую проблему. Вы не знаете, как преобразовать цепочку if в match?

tadman 18.05.2023 00:17

Вы также можете использовать свой начальный match на экране, добавив ветку _ => { ...error handler... }.

tadman 18.05.2023 00:18

да. когда я использую совпадение с variabe типа String, мне пришлось преобразовать тип String в тип &str с помощью .as_str(), но когда я пытаюсь использовать то же выражение совпадения с выражением if let, выдает ошибку, говорящую, что ожидаемая &str получила строку.

John French 18.05.2023 00:29

Это правда, вы не можете сопоставить напрямую на String, но вы можете на &str через as_str(). Вы делаете это уже с кодом предупреждения вашего устройства. Я говорю, что вы можете расширить это вместо цепочки if.

tadman 18.05.2023 00:30

извините, мой код очень компактный и его трудно читать. попробую отредактировать. и учтите это в следующий раз. Да, я попробовал обработчик ошибок, и он его ловит. там нет проблем. просто после уведомления об ошибке std::io возвращается к началу цикла. Я пытаюсь связать это совпадение внутри цикла/если как-то так, чтобы, когда я выхожу из него, я мог нацелить вложенный цикл на «цель», а не начинать с начала, а также получить значение из согласованного оператора. извините, если это не имеет смысла .. спасибо за попытку

John French 18.05.2023 00:54

Большая часть проблем при чтении кода возникает из-за того, что он очень плотный, и в каждой отдельной строке происходит много всего. Подумайте о том, чтобы лучше расставлять интервалы, например x - y вместо x-y. Вы также можете опустить такие вещи, как :f32, если тип тривиально получен из вычислений, поскольку, например, value уже имеет правильный тип.

tadman 18.05.2023 01:09

Один из способов упростить выход из цикла — использовать функции, чтобы упростить управление потоком управления. Можно просто return.

tadman 18.05.2023 01:10

Rust имеет тенденцию ориентироваться на такие шаблоны, как «сохранять недопустимые состояния непредставимыми», то есть иметь enum TemperatureUnit, к которым вы можете добавить много функций. Точно так же сделайте struct Temperature { unit: TemperatureUnit, value: f32 } для обозначения температуры. Разбейте этот монолитный код на более мелкие и легко тестируемые части. То, что у вас есть, можно протестировать только как гигантский кусок кода, вы не можете проверить, что, скажем, конкретная строка работает правильно. Если бы эта строка была в функции, это было бы тривиально для #[test].

tadman 18.05.2023 01:12
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
8
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Логику программы еще можно упростить, пока здесь решаются только синтаксические проблемы:

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. большое спасибо.

John French 18.05.2023 12:05

Спасибо пользователю: 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!!");
        };

}

Другие вопросы по теме

Сопоставление контролей с зависимыми от времени ковариатами для пролеченных случаев с разным временем лечения без замены
Сортировка фрейма данных путем сопоставления нескольких столбцов и условий
Powershell -сопоставьте строку с, если она имеет один из определенных символов. I.E lastname_firstname не соответствует lastname_firstname_middleinitail
Достижимо ли это каким-либо образом, у меня есть 3 строки со следующими суммами -5, 3, 2. Мне нужно найти смещение и найти сумму 0
Как искать одну или несколько строк в файле с помощью регулярного выражения и подсчитывать количество каждой строки отдельно?
Условное регулярное выражение для соответствия префиксу (и или) суффиксу, но не слову ни с одним из них
Как перебрать список в столбце в pandas, чтобы найти совпадение?
Найдите совпадение в строке и вставьте этот результат в каждую следующую строку, пока он не совпадет с END
Если ячейка соответствует условию, найдите следующее значение в столбце и верните его соседнее значение
ИНДЕКС и соответствие нескольким критериям