Sma*_*ell 3 reference match rust borrow
&str
在 Rust 中,人们经常看到以参数为参数的函数。
fn foo(bar: &str) {
println!("{}", bar);
}
Run Code Online (Sandbox Code Playgroud)
String
当调用这样的函数时,通过引用 a 作为参数传递它是完全可以的。
let bar = String::from("bar");
foo(&bar);
Run Code Online (Sandbox Code Playgroud)
严格来说,传递的参数是 an&String
并且函数期望是 an &str
,但是 Rust(正如人们所希望的那样)只是计算出来并且一切正常。然而,match 语句的情况并非如此。bar
如果我尝试在匹配语句中使用与之前相同的变量,则天真的用法将无法编译:
match &bar {
"foo" => println!("foo"),
"bar" => println!("bar"),
_ => println!("Something else")
};
Run Code Online (Sandbox Code Playgroud)
Rustc 抱怨它本来期待一个,&str
但收到了一个&String
。问题和解决方案都非常明显:只需bar
更明确地借用.as_str()
. 但这让我想到了真正的问题:为什么会这样?
如果 Rust 能够发现在函数参数的情况下an&String
可以简单地转换为 an ,为什么它不能用 match 语句做同样的事情呢?&str
这是类型系统限制的结果,还是使用 match 语句进行更奇特的借用是否存在隐藏的不安全性?或者这只是生活质量改善融入某些地方而不是其他地方的一个例子?我确信了解类型系统的人有答案,但互联网上关于这种行为小怪癖的信息似乎很少。
它不起作用的技术原因是因为match
审查者不是强制站点。如您的示例所示foo(&bar)
,函数参数可能是强制转换站点;并且它允许您由于强制而将 a&String
作为 a传递。&str
Deref
它不是强制站点的一个可能原因是没有明确的类型应该被强制。在您的示例中,您希望它是这样的,&str
因为它与字符串文字匹配,但是怎么样:
match &string_to_inspect {
"special" => println!("this is a special string"),
other => println!("this is a string with capacity: {}", other.capacity()),
};
Run Code Online (Sandbox Code Playgroud)
人们希望 的match
行为就像&str
与文字相匹配,但因为匹配是在 a 上,所以人们也&String
希望other
是 a 。&String
怎样才能同时满足呢?下一个合乎逻辑的步骤是让每个模式根据需要进行强制,这是人们非常希望的……但它会打开一整罐蠕虫,因为它Deref
是用户可定义的。有关更多信息,请参阅Rust 语言团队的deref 模式。
归档时间: |
|
查看次数: |
85 次 |
最近记录: |