В чем разница между Some(v) и Some(&v)?

И code block 1, и code block 2 в приведенном ниже коде работают, но я не знаю, почему.
В чем разница между Some(&number) и 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."),
    }

}

Они эквивалентны из-за автоматического определения и соответствия эргономике.

cdhowie 18.05.2023 06:05
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
2
1
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В contacts.get("Daniel") тип аргумента &str.

В contacts.get(&"Daniel") тип аргумента &&str.

Метод get()HashMap реализован следующим образом:

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.

Другие вопросы по теме