如何在未分配的情况下注释rust变量的数据类型?

时间:2019-06-01 01:41:38

标签: types rust variable-assignment

我是rust的新手,我想声明一个类型化的变量而不对其进行初始化。在Rust中这可能吗?如果是这样,是明智的选择还是有更好的,更多的仿制方法呢?

我正在查看rustlings中的以下代码,由于无法推断x的类型而无法编译:

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

所以,我尝试了这个:

let x: i32;

但是,现在编译器将在比较行上抛出一个错误,指出未声明x。

这很好,但是我想知道是否可以在没有分配的情况下声明类型。

let x: i32 = 10;

或者正确的方法是设计代码来避免这种情况吗?我来自C语言背景,对类型的懒惰可能有点太自在了。

2 个答案:

答案 0 :(得分:0)

在rust中,变量的类型通常是根据上下文推断的。
上下文可以包括以下任何内容:

  • 要分配的值的类型:
let x = String::new(); //x is now a String
  • 被调用函数的返回类型:
fn foo() -> usize {
    40
}
let x = foo(); //x is now usize

但是如果您没有要推断的类型,那么就不会为变量赋值:

let x;

然后,锈将无法推断出类型。因此,it will get mad at you

此答案中需要解决的另一个问题;锈不允许读取未初始化的变量这一事实。以下值x未初始化:

let x: u32;

读取未初始化的u32的值可能不会做太多,但是请考虑以下因素:

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

如果我们要为此提供一个安全的包装器,那将是完全可以的,毕竟,这实际上就是stdlib String的含义。但是,如果我们拥有一个未初始化的MyString并尝试读取其内容,那么最终将从ptr读取一个垃圾地址,并从一个垃圾len和{{1 }}。这将导致读取垃圾指针,这是未定义的行为,这是rust消除的第一要务。

所以,回顾一下:
✓每个变量在运行时都必须具有可确定的类型(包括擦除的类型,因为它们也是具体的类型[{capimpl Trait],但是dyn Trait是特殊的。)
✓必须先为每个变量分配某种值,然后才能读取其值。
✓Rust非常努力地消除所有未定义的行为。

答案 1 :(得分:0)

您可以执行此操作,前提是编译器可以在尝试读取之前始终为其分配一个值,并且只会分配一次。这在特殊情况下可能会有所帮助。这是a slightly contrived example

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"
}