Some(v)和Some(&v)之间有什么区别?

huangapple go评论87阅读模式
英文:

What's the difference between Some(v) and Some(&v)?

问题

以下是您要翻译的内容:

  1. `code block 1` 和下面的代码中的 `code block 2` 都有效,但我不知道为什么。
  2. `Some(&number)` `Some(number)` 之间有什么区别?
  3. ```rust
  4. use std::collections::HashMap;
  5. fn call(number: &str) -> &str {
  6. match number {
  7. "798-1364" => "We're sorry, please hang up and try again.",
  8. "645-7689" => "Hello, what can I get for you today?",
  9. _ => "Hi! Who is this again?"
  10. }
  11. }
  12. fn main() {
  13. let mut contacts = HashMap::new();
  14. contacts.insert("Daniel", "798-1364");
  15. //====== 代码块 1
  16. match contacts.get(&"Daniel") {
  17. Some(&number) => println!("Calling Daniel: {}", call(&number)),
  18. _ => println!("Don't have Daniel's number."),
  19. }
  20. //====== 代码块 2, 没有 '&'
  21. match contacts.get("Daniel") {
  22. Some(number) => println!("Calling Daniel: {}", call(number)),
  23. _ => println!("Don't have Daniel's number."),
  24. }
  25. }
英文:

Both code block 1 and code block 2 in below code work, but I don't know why.
What's the difference between Some(&number) and Some(number) ?

  1. use std::collections::HashMap;
  2. fn call(number: &str) -> &str {
  3. match number {
  4. "798-1364" => "We're sorry, please hang up and try again.",
  5. "645-7689" => "Hello, what can I get for you today?",
  6. _ => "Hi! Who is this again?"
  7. }
  8. }
  9. fn main() {
  10. let mut contacts = HashMap::new();
  11. contacts.insert("Daniel", "798-1364");
  12. //====== code block 1
  13. match contacts.get(&"Daniel") {
  14. Some(&number) => println!("Calling Daniel: {}", call(&number)),
  15. _ => println!("Don't have Daniel's number."),
  16. }
  17. //====== code block 2, without '&'
  18. match contacts.get("Daniel") {
  19. Some(number) => println!("Calling Daniel: {}", call(number)),
  20. _ => println!("Don't have Daniel's number."),
  21. }
  22. }

答案1

得分: 2

contacts.get("Daniel") 中,参数的类型是 &str

contacts.get(&"Daniel") 中,参数的类型是 &&str

HashMapget() 方法的实现如下:

  1. pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
  2. where
  3. K: Borrow<Q>,
  4. Q: Hash + Eq,
  5. {
  6. self.base.get(k)
  7. }

当您传递 &&str 时,Rust 编译器会自动将 &&str 解引用为 &str。因此,您的两个版本实质上是等价的。

在您的 match 分支 中:

  • Some(&number)number 的类型是 &str
  • Some(number)number 的类型是 &&str

再次提醒,由于 Rust 的自动解引用规则,两者实质上是相同的。

请注意,如果您写成了 Some(&&number)number 的类型将会是 str,并且将会出现以下编译错误信息:

  1. the size for values of type `str` cannot be known at compilation time

但是当您使用 &&T 甚至是 &&&&&T 时,它会起到与 &T 相同的作用。

英文:

In contacts.get("Daniel") the type of the argument is &str.

In contacts.get(&"Daniel") the type of the argument is &&str.

The HashMap's get() method is implemented as follows:

  1. pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
  2. where
  3. K: Borrow<Q>,
  4. Q: Hash + Eq,
  5. {
  6. self.base.get(k)
  7. }

When you pass &&str, the Rust compiler automatically dereferences &&str to &str. As a result, both your versions are essentially equivalent.

In your match arm:

  • Some(&number) the type of number is &str,
  • Some(number) the type of number is &&str.

Again, due to Rust's auto-dereference rules, both are essentially the same.

Note that if you had written Some(&&number), the type of number would have been str and that wouldn't compile with the message:

  1. the size for values of type `str` cannot be known at compilation time

But when you have &&T or even &&&&&T, that acts as if you had &T.

huangapple
  • 本文由 发表于 2023年5月18日 11:34:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定