为什么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;
答案 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阻止你做一些似乎没问题的事情。