i32::checked_add în Rust

Adună și returnează Some(rezultat) sau None dacă rezultatul depășește limitele tipului.

Sintaxă
const fn checked_add(self, rhs: i32) -> Option<i32>
// la fel: checked_sub, checked_mul, checked_div, checked_rem

Ce face i32::checked_add

a.checked_add(b) returnează Some(a + b) dacă suma încape în i32 și None dacă ar depăși. Nu intră niciodată în panică, nici în debug, nici în release. Familia completă: checked_sub, checked_mul, checked_div și checked_rem (acestea două dau None și la împărțirea la zero), checked_pow, checked_neg.

Este alegerea potrivită când depășirea înseamnă o eroare pe care vrei s-o tratezi: sume de bani, cantități, indici calculați din date de intrare. Rezultatul Option se combină ușor cu ? sau cu ok_or.

Parametri

Parametru Descriere
rhs Al doilea termen.

Ce returnează

Option<i32>.

Exemple

Exemplul 1: Toate operațiile verificate

fn main() {
    let mare = i32::MAX - 5;
    println!("checked_add(3):  {:?}", mare.checked_add(3));
    println!("checked_add(10): {:?}", mare.checked_add(10));
    println!("checked_sub:     {:?}", i32::MIN.checked_sub(1));
    println!("checked_mul:     {:?}", 50_000_i32.checked_mul(50_000));
    println!("checked_div(0):  {:?}", 10_i32.checked_div(0));
    println!("checked_div(3):  {:?}", 10_i32.checked_div(3));
}

Rezultat

checked_add(3):  Some(2147483645)
checked_add(10): None
checked_sub:     None
checked_mul:     None
checked_div(0):  None
checked_div(3):  Some(3)

Exemplul 2: Total de coș fără depășire

Prețurile sunt în bani (1 leu = 100 de bani). Funcția returnează eroare dacă totalul ar depăși limita.

fn total(preturi_bani: &[i32], cantitati: &[i32]) -> Result<i32, String> {
    let mut suma: i32 = 0;
    for (p, c) in preturi_bani.iter().zip(cantitati) {
        let linie = p.checked_mul(*c).ok_or("valoare prea mare pe o linie")?;
        suma = suma.checked_add(linie).ok_or("totalul este prea mare")?;
    }
    Ok(suma)
}

fn main() {
    println!("{:?}", total(&[1250, 499], &[2, 3]));
    println!("{:?}", total(&[99_900_000, 1], &[30, 1]));
    println!("{:?}", total(&[2_000_000_000, 500_000_000], &[1, 1]));
}

Rezultat

Ok(3997)
Err("valoare prea mare pe o linie")
Err("totalul este prea mare")

Greșeli frecvente

  • Verifici depășirea după operație (if a + b < a): în debug programul intră în panică înainte de verificare. Folosește checked_add.
  • Scrii a.checked_add(b).unwrap(): ai aceeași panică, doar cu alt mesaj. Tratează None.

Comenzi înrudite

  • i32::saturating_sub: Scade, dar se oprește la limita tipului în loc să depășească: i32::MIN.saturating_sub(1) rămâne i32::MIN.
  • i32::wrapping_add: Adună cu „întoarcere”: după MAX urmează MIN. overflowing_add spune și dacă a avut loc depășirea.
  • i32: Tipul implicit pentru numere întregi cu semn, pe 32 de biți: de la -2147483648 la 2147483647.
  • Option::ok_or: Transformă un Option în Result: Some(x) devine Ok(x), iar None devine Err cu eroarea dată.