英文:
What's the difference between Some(v) and Some(&v)?
问题
以下是您要翻译的内容:
`code block 1` 和下面的代码中的 `code block 2` 都有效,但我不知道为什么。
`Some(&number)` 和 `Some(number)` 之间有什么区别?
```rust
use std::collections::HashMap;
fn call(number: &str) -> &str {
    match number {
        "798-1364" => "We're sorry, please hang up and try again.",
        "645-7689" => "Hello, what can I get for you today?",
        _ => "Hi! Who is this again?"
    }
}
fn main() { 
    let mut contacts = HashMap::new();
    contacts.insert("Daniel", "798-1364");
    //====== 代码块 1
    match contacts.get(&"Daniel") {
        Some(&number) => println!("Calling Daniel: {}", call(&number)),
        _ => println!("Don't have Daniel's number."),
    }
    //====== 代码块 2, 没有 '&'
    match contacts.get("Daniel") {
        Some(number) => println!("Calling Daniel: {}", call(number)),
        _ => println!("Don't have Daniel's number."),
    }
}
英文:
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) ?
use std::collections::HashMap;
fn call(number: &str) -> &str {
    match number {
        "798-1364" => "We're sorry, please hang up and try again.",
        "645-7689" => "Hello, what can I get for you today?",
        _ => "Hi! Who is this again?"
    }
}
fn main() { 
    let mut contacts = HashMap::new();
    contacts.insert("Daniel", "798-1364");
    //====== code block 1
    match contacts.get(&"Daniel") {
        Some(&number) => println!("Calling Daniel: {}", call(&number)),
        _ => println!("Don't have Daniel's number."),
    }
    //====== code block 2, without '&'
    match contacts.get("Daniel") {
        Some(number) => println!("Calling Daniel: {}", call(number)),
        _ => println!("Don't have Daniel's number."),
    }
}
答案1
得分: 2
在 contacts.get("Daniel") 中,参数的类型是 &str。
在 contacts.get(&"Daniel") 中,参数的类型是 &&str。
HashMap 的 get() 方法的实现如下:
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where
    K: Borrow<Q>,
    Q: Hash + Eq,
{
    self.base.get(k)
}
当您传递 &&str 时,Rust 编译器会自动将 &&str 解引用为 &str。因此,您的两个版本实质上是等价的。
在您的 match 分支 中:
Some(&number)中number的类型是&str,Some(number)中number的类型是&&str。
再次提醒,由于 Rust 的自动解引用规则,两者实质上是相同的。
请注意,如果您写成了 Some(&&number),number 的类型将会是 str,并且将会出现以下编译错误信息:
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:
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where
    K: Borrow<Q>,
    Q: Hash + Eq,
{
    self.base.get(k)
}
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 ofnumberis&str,Some(number)the type ofnumberis&&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:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论