rust中引用与值的显式注释
所以在Rust中,有一件事让我感到困惑,那就是当涉及到一个值和一个引用时的类型推断能力。比如说,rust中引用与值的显式注释,rust,Rust,所以在Rust中,有一件事让我感到困惑,那就是当涉及到一个值和一个引用时的类型推断能力。比如说, fn main() { let s1 = String::from("h1"); let s2 = &s1; println!("string is {}", s1); } 借用检查器允许编译,但我不知道为什么?s2在这里是一个值还是被推断为对s1的引用 在C++中,通过引用初始化一个新值将创建一个副本,除非该变量被明确声明为引用: #include <st
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
}
#包括
int main(int argc,char const*argv[]{
std::字符串s1(“Hello”);
std::string&s2=s1;//引用
std::string s3=s2;//复制
}
所以在rust中,我的问题是,类型推断是否也适用于引用与值的情况?如果是,什么时候需要显式地将变量声明为引用?我的类型是什么?
s2
的类型是&std::string::string
,通常表示为简单的&string
s2
以(只读)引用的形式借用了s1
(&
),当s2
在范围内时,将阻止s1
被写入(如果它是可变的)
我将来如何自己决定?
如果您想让编译器显示特定绑定的类型,一个常见的习惯用法是使用let()=some\u绑定代码>。编译器将给您一个错误,显示某些绑定的类型
我注意到编译器似乎通过省略前导的&
而起到了“帮助”的作用,因此,当您习惯于使用Rust时,我建议尝试使用错误的类型调用伪函数,这会显示绑定的完整类型。在这里,编译器确实显示了调用参数的完整类型,您可以看到它是&String
显式声明类型(处理OP的注释):
关于在C++中显式声明类型>声明> <代码>,如C++(),RID支持类似的:
设a:u32=42;
//平等的
设b=42_u32;
对于构造类型,类型将是类型构造函数返回的任何类型:
//似乎有些多余(因为`String::new()`返回`String`)
//但这是完全合法的
让c:String=String::new(“你好,世界!”);
//等价物
让d=String::new(“你好,世界!”);
因此,只要编译器可以从右边明确地确定类型,就可以推断出let
的类型
注意:类型规范对于const
绑定仍然是强制性的:
//错误:尽管RHS上有显式类型声明,但类型仍然是必需的
//常数foo=42_u32;
//由于必须显式定义类型,因此在RHS上再次指定是多余的
//(但合法):
常数foo:u32=42_32;
//表示“const”的质朴的(惯用的)`
常数条:u32=42;
从typechecker的角度来看,结构值和对结构值的引用是两种不同的类型。这可能是让您感到不快的原因吗?在rust示例中,s2是推断为引用还是从引用创建的新值?&s1
表示您有一个引用类型。我明白了,因此不需要在let
侧显式声明。另一件需要澄清的事情是,生锈通常会移动值,而不是复制值。如果要在Rust示例中添加一行let s3=s1
,例如,那么它将无法编译,因为该值已从s1
移到s3
中。可以使用“<代码>克隆> /COD>特性来显式创建一个值的新副本(例如,代码> S3= S1. CalOne())/代码>,并且<<代码>拷贝<代码>特性可以用来允许位复制的隐式位(例如I32等基元)。另外一点要考虑:RISE比C++更省略隐式类型转换。所以OP的C++示例(复制模式)中第三行的直接翻译为<代码> S3:String=S2;<代码>并且不编译。它需要显式调用s2.to_string()
。