我知道在0.6中删除了可变字段.我用这段代码得到以下错误,
C:\ Users\mflamer\Dropbox\Rust\Tests\gmap.rs:23:8:23:18错误:分配到不可变字段C:\ Users\mflamer\Dropbox\Rust\Tests\gmap.rs:23 dart. alpha = vec :: from_elem(self.n + 1,dart);
我在这做错了什么?谢谢.
pub struct GMap<T> {
priv n: uint,
priv darts: ~[Dart<T>]
}
struct Dart<T> {
alpha: ~[@Dart<T>],
embed: ~[@T],
tagged: bool
}
impl<T> GMap<T> {
pub fn new(dim: uint) -> GMap<T> {
let mut map: GMap<T> = GMap{n: dim, darts: ~[]};
return map
}
pub fn new_dart(&self, ) -> @Dart<T> {
let mut dart = @Dart{alpha: ~[], embed: ~[], tagged: false};
dart.alpha = vec::from_elem(self.n + 1, dart);
//dart.embed = vec::from_elem(self.n + 1, );
return dart;
}
pub fn dim(&self) -> uint {
self.n
}
}
//pub fn traverse(&self,[bool,..])
enum Cell {
Null,
Vertex,
Edge,
Face,
Solid
}
fn main() {
let topo: GMap<Cell> = GMap::new(3);
}
Run Code Online (Sandbox Code Playgroud)
问题是可变性如何通过所有权继承.对于可变的东西,它的拥有者必须是可变的.除了通过新的所有者之外,所有权继承,@并且&被归类为所有者.所以在这种情况下,你dart拥有@Dart盒子,但不是盒子的内容,所以muton x并不意味着盒子的内容是可变的(实际上,它不可能是可变的,因为否则它可能会改变引用它的其他东西的脚).
解决这个问题的方法是使盒子成为一个可变的盒子,这样dart结构的所有者是可变的,即@mut Dart { .. }(这有一个(小的)运行时惩罚,并且如果它在借用时发生变异,可能会使程序失败作为不可变的),或一次性构建它.前者不是最优的,后者听起来很难实现.但是,前者可能看起来像:
struct Dart<T> {
alpha: ~[@mut Dart<T>],
embed: ~[@T],
tagged: bool
}
// ...
pub fn new_dart(&self, ) -> @mut Dart<T> {
let dart = @mut Dart{alpha: ~[], embed: ~[], tagged: false};
dart.alpha = vec::from_elem(self.n + 1, dart);
//dart.embed = vec::from_elem(self.n + 1, );
return dart;
}
Run Code Online (Sandbox Code Playgroud)
(非@mut解决方案需要的是"打结",但我不清楚如何让它在Rust中工作.)
| 归档时间: |
|
| 查看次数: |
6570 次 |
| 最近记录: |