为什么在指针移动后分配给指针的成员仍然有效?

时间:2017-10-19 15:14:57

标签: rust

为什么Option::Some在此示例中仍然有效?它已被移至struct MyRecordRec2<'a> { pub id: u32, pub name: &'a str, pub next: Box<Option<MyRecordRec2<'a>>> } #[test] fn creating_circular_recursive_data_structure() { let mut n1_mut = MyRecordRec2 { id: 1, name: "n1", next: Box::new(None) }; let n2 = MyRecordRec2 { id: 2, name: "n2", next: Box::new(Some(n1_mut)) }; //Why is n1_mut still valid? n1_mut.next = Box::new(Some(n2)); } ,所以它不应该无效吗?

#[test]
fn creating_and_freezing_circular_recursive_data_structure() {
    let loop_entry = {
        let mut n1_mut = MyRecordRec2 {
            id: 1,
            name: "n1",
            next: Box::new(None),
        };

        let n2 = MyRecordRec2 {
            id: 2,
            name: "n2",
            next: Box::new(Some(n1_mut)),
        };

        n1_mut.next = Box::new(Some(n2));

        n1_mut
    };
}

以下内容无法使用熟悉的&#34;使用移动值&#34;错误:

error[E0382]: use of moved value: `n1_mut`
  --> src/main.rs:44:9
   |
39 |             next: Box::new(Some(n1_mut)),
   |                                 ------ value moved here
...
44 |         n1_mut
   |         ^^^^^^ value used here after move
   |
   = note: move occurs because `n1_mut` has type `MyRecordRec2<'_>`, which does not implement the `Copy` trait
    import React, { Component } from 'react';
import {
    View,
    Text,
    NetInfo
} from 'react-native';

// styles
import { style } from './style';
import { globalStyle } from '../../assets/styles/globalStyle';

// redux
import {connect} from 'react-redux';
import * as actions from '../../actions';

class InternetConnectionPopUp extends Component {
    constructor(props){
        super(props);
        this.state = { 
            connectionInfo : ''

         }
         this.handleFirstConnectivityChange = this.handleFirstConnectivityChange.bind(this);

    }  
    handleFirstConnectivityChange(connectionInfo) {
        this.setState({
            connectionInfo: connectionInfo.type
        })
        console.log('First change, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);

      }

    componentWillMount () {
        NetInfo.getConnectionInfo().then((connectionInfo) => {
            this.setState({
                connectionInfo: connectionInfo.type
            })
            //console.log('Initial, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);
          });

          NetInfo.addEventListener(
            'connectionChange',
            this.handleFirstConnectivityChange
          );
    }
    componentWillUnmount() {
        NetInfo.removeEventListener(
            'connectionChange',
            handleFirstConnectivityChange
          );
    }




    render() {


        return (
            <View>
                <Text> ComponentName component </Text>
                <Text> { this.state.connectionInfo } </Text>
            </View>    
        );
    }
}


export default InternetConnectionPopUp;

1 个答案:

答案 0 :(得分:8)

这与指针没有任何关系;这也有效:

#[derive(Debug)]
struct NonCopy;

#[derive(Debug)]
struct Example {
    name: NonCopy,
}

fn main() {
    let mut foo = Example {
        name: NonCopy,
    };

    drop(foo);

    foo.name = NonCopy;
}

虽然我找不到我之前见过的类似SO问题,但quote from nikomatsakis描述了它:

  

通常,移动的粒度非常窄。我们打算最终允许您“填充”两个字段,然后再次使用该结构。我想这在今天不起作用。我必须再看一下移动代码,但我认为总的来说,我想要追求1.0版的一个原因是扩展类型系统以更好地处理已经移动的东西(特别是我想支持移出&amp; mut指针,只要你在做任何错误之前恢复该值)。无论如何,我认为这个例子或多或少都不会以一般的方式处理事物,尽管你可以想象规则说“如果你移动f,你再也不能触及f的任何子域而不将f恢复为一个单位”。

还讨论the Rust subreddit,它链接到Rust issue 21232: "borrow-checker allows partial reinit of struct that has been moved away, but no use of it"

从概念上讲,除了结构本身之外,结构中的每个字段都有一个标志 - 我喜欢考虑Chris Morgan's cardboard box analogy。只要在使用结构之前重新进入,就可以移出拥有的struct的字段:

drop(foo.name);
foo.name = NonCopy;

println!("{:?}", foo);

显然,自2014年以来,没有人愿意在重新填充字段后再次将整个结构标记为有效。

实际上,您并不真正需要此功能,因为您可以立即分配整个变量。当前的实现过于安全,因为Rust阻止你做一些似乎没问题的事情。