Как добавить отрицательное число i32 в переменную usize? - PullRequest
0 голосов
/ 04 января 2019

Например:

let mut a : usize = 0xFF;
a += -1;  // -1 may be from other variable, so there can't be a -= 1;
println!("{}", a);

Вывод:

error[E0277]: the trait bound `usize: std::ops::Neg` is not satisfied

все равно

1 Ответ

0 голосов
/ 04 января 2019

Ваша попытка не работает, потому что в Rust вы можете выполнять операции только между строго схожими типами.Rust не делает никакого неявного числового приведения, потому что это будет выстрел в ногу, как вы можете видеть ниже: у вас есть особый случай и несколько способов переполнения.

В одну сторонупойти - привести абсолютное значение от i32 к usize и добавить или удалить его в зависимости от того, является ли оно отрицательным или положительным.Однако вы должны обработать особый случай минимального значения, которое переполняется, когда вы принимаете его абсолютное значение:

fn add(u: usize, i: i32) -> usize {
    if i.is_negative() {
        u - i.wrapping_abs() as u32 as usize
    } else {
        u + i as usize
    }
}

fn main() {
    let u = 7;
    let i1 = -1;
    let i2 = 1;
    let min = -2_147_483_648;

    assert_eq!(add(u, i1), 6);
    assert_eq!(add(u, i2), 8);
    assert_eq!(add(3_000_000_000, min), 852_516_352);
}

Вы также можете проверить переполнения:

fn add(u: usize, i: i32) -> Option<usize> {
    if i.is_negative() {
        u.checked_sub(i.wrapping_abs() as u32 as usize)
    } else {
        u.checked_add(i as usize)
    }
}

fn main() {
    let u = 7;
    let i1 = -1;
    let i2 = 1;

    assert_eq!(add(u, i1), Some(6));
    assert_eq!(add(u, i2), Some(8));
    assert_eq!(add(0, -1), None);
}
...