【问题标题】:What is the difference between `e1` and `&e2` when used as the for-loop variable?当用作 for 循环变量时,`e1` 和 `&e2` 有什么区别?
【发布时间】:2017-12-25 03:42:00
【问题描述】:

编译器说e1: &i32e2: i32。阅读文档for slice::Iterthe book chapter on loops 后,我仍然感到困惑。

更一般地说,可以拥有切片中的特定元素吗?在情况 2 中,e2 似乎拥有一个元素,是吗?

fn main() {
    let slice = &[1, 2, 3];
    for e1 in slice.iter() {
        println!("{}", e1); // case 1
    }

    for &e2 in slice.iter() {
        println!("{}", e2); // case 2
    }
}

【问题讨论】:

    标签: rust


    【解决方案1】:

    解构模式绑定中使用时,& 符号& 用于取消引用值:

    let a_number: i32 = 42;
    let a_reference_to_a_number: &i32 = &a_number;
    
    let another_reference = a_reference_to_a_number;
    let &another_number = a_reference_to_a_number;
    
    let () = another_reference; // expected type `&i32`
    let () = another_number;    // expected type `i32`
    

    这适用于任何接受模式的地方,例如在letif let 中,作为函数参数、for 循环变量或匹配臂。


    虽然最初让很多人感到困惑,但这实际上是语言与枚举和结构的模式匹配方式一致,因此从内部变量绑定中删除

    let a_value: Option<&i32> = Some(&42);
    
    if let Some(&val) = a_value {
        let () = val; // expected type `i32`
    }
    

    注意val 不再被Some“包裹”,就像它不再被引用“包裹”一样。

    &amp; 在模式中的这种行为是需要 ref 关键字的原因。 ref 关键字用于明确引入模式匹配中的引用。

    【讨论】:

    • 我明白了。所有权是否转移到e2(在我的示例中)?
    • @qweruiop 与在第一个循环中使用 *e1 的情况相同或更少。 i32 实现 Copy,因此它将复制这些位。如果它没有实现Copy,你会得到“不能移出借用的上下文”错误。默认情况下,您不能拥有引用背后的值的所有权,因为这样做会使被引用的项目处于未知状态。
    • 好的。我尝试使用没有Copy 的结构,但确实收到了借用错误。是否相当于说:如果一个值有引用,那么它的所有权就不能通过它的 refs 获取?
    • @qweruiop 相当于哪个部分?您可以永远通过参考转让所有权。如果您引用了实现Copy 的东西,那么取消引用它可能会继续并制作该副本。如果它实现了Clone,您可以在参考上调用clone 并获得您拥有的东西。在任何一种情况下,引用所指向的值的原始所有者仍然拥有该值。
    • 到“默认是 [...]”。但我想我明白了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-10-01
    • 2011-04-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2020-01-03
    • 2021-06-28
    • 2021-12-27
    相关资源
    最近更新 更多