显式注释的引用与rust中的值

时间:2019-04-29 17:04:11

标签: rust

因此,在Rust中,我不解的是关于值与引用的类型推断能力。例如,

fn main() {
    let s1 = String::from("h1");
    let s2 = &s1;
    println!("string is {}", s1);
} 

借位检查器允许对此进行编译,但是我不确定为什么吗? s2是这里的值,还是被推断为对s1的引用?

在C ++中,通过引用初始化新值将创建一个副本,除非将该变量明确声明为引用:

#include <string>

int main(int argc, char const* argv[]) {
    std::string s1("Hello");
    std::string& s2 = s1; // reference
    std::string s3 = s2; // copy
}

所以在锈病中,我的问题是,类型推断是否也适用于引用与值的情况?如果是这样,什么时候需要显式声明变量作为引用?

1 个答案:

答案 0 :(得分:2)

我是什么类型?

s2的类型为&std::string::String,通常更简单地表示为&String

s2s1的借用,以(只读)引用(&)的形式出现,会阻止将s1写入( (如果它是可变的),而s2在范围内。

我将来如何自行确定?

Sample code on Playground

如果您想让编译器揭示特定绑定的类型,则通常的习惯用法是使用let () = some_binding;。编译器会给您一个错误,显示some_binding的类型。

我注意到编译器似乎通过省略开头的&来“帮助”,所以当您对Rust感到满意时,我建议尝试使用错误类型调用伪函数,以显示绑定的完整类型。在这里,编译器确实揭示了调用参数的完整类型,您可以看到的是&String

明确声明类型(解决OP的评论):

与在C ++(see 'AAA')中一样,在声明的let端显式声明类型,Rust支持类似的东西:

let a: u32 = 42;

// equvialent
let b = 42_u32;

对于构造类型,类型将是构造函数返回的类型:

// seems somewhat redundant (since `String::new()` returns `String`) 
// but is perfectly legal
let c: String = String::new("Hello, world!");

// equivalent
let d = String::new("Hello, world!");

只要编译器可以从右侧明确确定类型,就可以为let推断类型。

注意:对于const绑定,类型规范仍然是必需的:

// error: despite the explicit type declaration on the RHS, the type is still required
//const foo = 42_u32;

// since the type must be explicitly defined specifying again on the RHS is redundant
// (but legal):
const foo: u32 = 42_u32;

// Rustic (idiomatic) for `const`
const bar: u32 = 42;