解除引用运算符在 Rust 中如何工作?

问题描述 投票:0回答:1
    // https://cses.fi/problemset/task/1621
    
    use std::collections::HashSet;
    
    fn main() {
        let mut inp: String = String::new();
        std::io::stdin()
            .read_line(&mut inp)
            .expect("Error in input");
        let n: u64 = inp.trim().parse().expect("Error in parsing to int");
        inp.clear();
        std::io::stdin()
            .read_line(&mut inp)
            .expect("Error in input");
        let x: Vec<u64> = inp
            .split_whitespace()
            .map(|s| s.parse().expect("Error in input"))
            .collect();
        println!("x: {:?}", x);
        let mut map: HashSet<u64> = HashSet::new();
        // Use a for loop to insert values into the HashSet
        for key in &x {
            map.insert(*key);
        }
        println!("{}", map.len());
        println!("x: {:?}", x);
        println!("map: {:?}", map);
    }

结果:

5
1 2 3 3
x: [1, 2, 3, 3]
3
x: [1, 2, 3, 3]
map: {2, 1, 3}

有人可以解释一下所有权吗

输入 &x { 地图.插入(*键); }

我们是否在这里使用引用运算符创建密钥的副本?如果数组的元素是 String 类型怎么办?

rust ownership
1个回答
0
投票

for key in &x { map.insert(*key); }
行中,您正在迭代对向量
x
中元素的引用。
&
中的
&x
表示“借用
x
”或“获取对
x
的引用”。这允许您访问
x
的元素,而无需获取它们的所有权。

当您执行

*key
时,您将取消引用引用以获取实际值。在这种情况下,因为
u64
实现了
Copy
特征,这实际上创建了该值的副本。这就是为什么您可以毫无问题地将其插入
HashSet

如果数组的元素属于

String
类型,您将无法简单地取消引用键来获取副本,因为
String
不实现
Copy
特性。相反,您必须克隆字符串以获得可以插入到
HashSet
中的副本。这看起来像
for key in &x { map.insert(key.clone()); }

或者,如果在此之后您不需要原始向量

x
,您可以获取字符串的所有权并将它们移动到
HashSet
中,而无需克隆。这看起来像
for key in x { map.insert(key); }
。请注意,这将使
x
之后为空。

© www.soinside.com 2019 - 2024. All rights reserved.