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

10 harrison314
položil/-a 3.6. 18:47

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. 19:56
  • harrison314 : Nie, toto sa vola ucenie sa noveho jazyka. 3.6. 20:24
  • Mlocik97 : Ok, ale fakt môžeš princíp skopírovať z C/C++. 3.6. 22:26
  • pudr : Asi si narazil na hranici svých možností :) 5.6. 13:27
odkaz
13 rmaslo
odpověděl/-a 13.6. 11:12
 
upravil/-a 13.6. 11:27

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.