【问题标题】:Mutable Struct Fields可变结构字段
【发布时间】:2013-06-02 02:47:24
【问题描述】:

我知道在 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);    
}

【问题讨论】:

    标签: rust


    【解决方案1】:

    问题在于可变性如何通过所有权继承。对于可变的东西,它的所有者必须是可变的。所有权继承,除非通过新的所有者,@&amp; 被归类为所有者。所以在这种情况下,您拥有dart 拥有@Dart 框,但不是框的内容,所以x 上的mut 并不意味着box 是可变的(实际上,它不可能是可变的,否则它可能会在引用它的其他东西的脚下发生变化)。

    解决这个问题的方法是使盒子成为可变盒子,以便 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;
        }
    

    (非@mut 解决方案需要"tying the knot",但我不清楚如何让它在Rust 中工作。)

    【讨论】:

    • 这些是我现在学习 rust 而不是使用 Haskell 的原因。我发现图形结构从来都不是很正确,并且总是需要这些技巧。再次感谢您的帮助。
    • 我想我们需要 letrec 或惰性 eval 来打结。
    • @MFlamer,通过futures 进行惰性评估,但这是一个重量级的解决方案。
    • 如果我将这个添加到上面的函数中,“self.darts.push(dart);”会怎样?因为这是一个结构体的方法,它在特定实例中可能是可变的,也可能不是可变的,Rust 是如何决定改变 self 是否有效的?
    • @MFlamer, &amp;mut self 可能也可以,而且更灵活一些。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 2016-07-11
    • 1970-01-01
    • 2019-11-17
    • 2015-01-21
    相关资源
    最近更新 更多