Как аннотировать тип данных переменных ржавчины без присваивания? - PullRequest
0 голосов
/ 01 июня 2019

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

Я смотрю на следующий код из rustlings , который не компилируется, потому что не может 't выводит тип x:

    let x;
    if x == 10 {
        println!("Ten!");
    }

Итак, я попробовал это:

let x: i32;

однако, теперь компилятор выдаст ошибку в строке сравнения, говоря, что x небыл объявлен.

Это прекрасно работает, но мне было интересно, можно ли объявить тип без присваивания.

let x: i32 = 10;

Или это правильный способ, включающий разработку кода дляизбегать таких ситуаций в первую очередь?Я родом из языка Си, и мне, наверное, слишком комфортно, когда я ленивый с типами.

Ответы [ 2 ]

0 голосов
/ 01 июня 2019

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

fn main() {
    let some_cond = false;

    let x;
    let y;
    let z: u8;

    if some_cond {
        x = 1;
        y = 2;
        z = 3;
    } else {
        x = 4;
        y = 5;
        z = 6;
    }

    println!("x = {}", x); // "x = 4"
    println!("y = {}", y); // "y = 5"
    println!("z - 10 = {}", z.wrapping_sub(10)); // "z - 10 = 252"
}
0 голосов
/ 01 июня 2019

В ржавчине тип переменной обычно выводится из контекста.
Контекст может включать в себя любое из следующего:

  • Тип присваиваемого значения:
let x = String::new(); //x is now a String
  • Тип возвращаемого значения вызываемой функции:
fn foo() -> usize {
    40
}
let x = foo(); //x is now usize

Но если у вас нет типа для вывода, то, как нетприсвоение переменной:

let x;

Тогда ржавчина не может определить тип.Следовательно, это разозлится на вас .

Еще одна проблема, которую необходимо решить в этом ответе;тот факт, что ржавчина не позволяет читать неинициализированные переменные.Следующее значение x неинициализировано:

let x: u32;

Считывание значения неинициализированного u32, вероятно, не слишком много, но примите во внимание следующее:

struct MyString {
    ptr: *const u8,
    len: usize,
    cap: usize,
}

Если бы мы предоставили безопасную оболочку для этого, это было бы прекрасно, в конце концов, это то, к чему сводится stdlib String.Но если бы мы владели неинициализированным MyString и попытались прочитать его содержимое, мы бы закончили чтение адреса мусора из ptr и мусора len и cap.Это привело бы к чтению указателя мусора, который является неопределенным поведением, что является приоритетом ржавчины №1 для устранения.

Итак, резюмируем:
✓ Каждая переменная должна иметь тип, определяемый во время выполнения (включая стертые типы, потому что это тоже конкретные типы [dyn Trait и impl Trait], но impl Trait особенное.)
✓ Каждой переменной должно быть присвоено какое-то значение, прежде чем вы сможете прочитать ее значение.
✓ Rust очень старается устранить all undefined поведению.

...