Rust- ako na krajsi program rubrika: Programování: Jiné

7 harrison314
položil/-a 3.6.2020

Zdravim,
zacinam sa ucit Rust a tak som si dal klasicke zadanie zo strednej - nacitat z konzoli tri cisla reprezentujuce dlzky hran trojuholnika, urcit ci sa z nich da vytvorit trojuholnik a vypocitat jeho obvod.

V C-ecku, zadanie na par riadkov, no v Rsute mi vysiel nasledujucic kod, ako by sa to dalo spravit lepsie (prosim len zo stnadardnou kniznicou)?

use std::io;
use std::io::BufRead;
 
struct TriangleEdges
{
    a:f64,
    b:f64,
    c:f64
}
 
impl TriangleEdges {
    fn print(&self) {
        println!("Triangle: a: {}, b: {}, c: {}", self.a, self.b, self.c);
    }
}
 
fn read_edges() -> Result<Box<TriangleEdges>, &'static str>
{
    let stdin = io::stdin();
    let stdin_lock = stdin.lock();
 
    let mut vec = Vec::new();
    for line in stdin_lock.lines().take(3) {
        match line {
            Ok(line_str) => match line_str.trim().parse::<f64>() {
               Ok(number) => vec.push(number),
               Err(_) => return Err("Value is not a number.")
            },
            Err(_) => return Err("Failed to read line.")
        }
    }
 
    return Ok(Box::new(TriangleEdges{ a: vec[0], b: vec[1], c:vec[2] }));
}
 
fn calculate_perimeter(p: Box<TriangleEdges>) -> Option<f64> {
 
    let (ma, tmp) = (p.a.min(p.b), p.a.max(p.b));
    let (mb, mc) = (tmp.min(p.c), tmp.max(p.c));
 
    if ma + mb > mc {
        return Some(p.a + p.b + p.c);
    }
    else
    {
        return None;
    }
}
 
fn main() {
    println!("Enter the triangle edges:");
 
    let triangle = read_edges();
    match triangle {
        Ok(t) => {
            t.print();
            match calculate_perimeter(t) {
                Some(perimeter) => println!("Perimeter is {}", perimeter),
                None => println!("Entered edges do not form a triangle.")
            }
        },
        Err(err) => println!("ERR: {}", err)
    }
}

Komentáře

  • Kit : Tomuhle se říká overengineering. Napiš to normálně jako v C - bude to kratší a přehlednější. 3.6.2020
  • harrison314 : Nie, toto sa vola ucenie sa noveho jazyka. 3.6.2020
  • Mlocik97 : Ok, ale fakt môžeš princíp skopírovať z C/C++. 3.6.2020
  • pudr : Asi si narazil na hranici svých možností :) 5.6.2020
odkaz
8 rmaslo
odpověděl/-a 13.6.2020
 
upravil/-a 13.6.2020

Rust neznám, ale obecně se ve funkci vždy snažím nejprve najít "chyby" (např.: nekonzistentní stavy, chybějící inicializace, atd...) a pokud jsou, tak okamžitě vypadnout (return či throw) a nezatahovat si to někam dál do kódu. Zbytek kódu se naopak snažím mít "čistý" tj. soustředěný jen na vlastní předpokládanou funkčnost.
Takhle, když je jeden druh chyby (jedna strana delší než součet ostatních) to není moc patrné, ale když těch možných "chyb" je víc, tak je to mnohem přehlednější (jinak se časem z těch if else zblázníš). Zároveň se snažím nic zbytečně nemaskovat a nekomplikovat, ať je všechno vidět na první pohled.
Takže za mne (byť to někomu může přijít takové "dětské" a "málo vědecké"):

fn calculate_perimeter(p: &TriangleEdges) -> Option<f64> {
    if (p.a > p.b + p.c) || (p.b > p.a + p.c) || (p.c > p.a + p.b) return None;
    return Some(p.a + p.b + p.c);
}

Komentáře

Pro zobrazení všech 4 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.