在鐵鏽社區的慷慨幫助下,我設法使用託管指針組裝了拓撲數據結構的基礎。這很好地融合在一起,我對Rust的整體感到非常興奮。然後我讀了這個post(這看起來像是一個合理的計劃),它激勵我回溯並儘可能地僅使用擁有的指針重新組裝它。圖結構中擁有的指針
這是使用管理指針的工作版本:
struct Dart<T> {
alpha: ~[@mut Dart<T>],
embed: ~[@mut T],
tagged: bool
}
impl<T> Dart<T> {
pub fn new(dim: uint) -> @mut Dart<T> {
let mut dart = @mut Dart{alpha: ~[], embed: ~[], tagged: false};
dart.alpha = vec::from_elem(dim, dart);
return dart;
}
pub fn get_dim(&self) -> uint {
return self.alpha.len();
}
pub fn traverse(@mut self, invs: &[uint], f: &fn(&Dart<T>)) {
let dim = self.get_dim();
for invs.each |i| {if *i >= dim {return}}; //test bounds on invs vec
if invs.len() == 2 {
let spread:int = int::abs(invs[1] as int - invs[0] as int);
if spread == 1 { //simple loop
let mut dart = self;
let mut i = invs[0];
while !dart.tagged {
dart.tagged = true;
f(dart);
dart = dart.alpha[i];
if i == invs[0] {i = invs[1];}
else {i == invs[0];}
} }
// else if spread == 2 { // max 4 cells traversed
// }
}
else {
let mut stack = ~[self];
self.tagged = true;
while !stack.is_empty() {
let mut dart = stack.pop();
f(dart);
for invs.each |i| {
if !dart.alpha[*i].tagged {
dart.alpha[*i].tagged = true;
stack.push(dart);
} } } } } }
追逐一生的錯誤的幾個小時裏,我已經得出結論之後,這甚至可能不會有可能與擁有的指針,由於週期性特徵(無需打結,因爲我是warned)。我對此的微弱嘗試如下。我的問題是,這種結構可以實現而不訴諸託管指針?如果不是,上面的代碼是否被認爲是合理的「生鏽」? (慣性生鏽)。謝謝。
struct GMap<'self,T> {
dim: uint,
darts: ~[~Dart<'self,T>]
}
struct Dart<'self,T> {
alpha: ~[&'self mut Dart<'self, T>],
embed: ~[&'self mut T],
tagged: bool
}
impl<'self, T> GMap<'self, T> {
pub fn new_dart(&'self mut self) {
let mut dart = ~Dart{alpha: ~[], embed: ~[], tagged: false};
let dartRef: &'self mut Dart<'self, T> = dart;
dartRef.alpha = vec::from_elem(self.dim, copy dartRef);
self.darts.push(dart);
}
}
似乎在這種情況下,託管指針版本(GC或RC)的開銷可能是值得的。如果我使用地圖或散列表來保持飛鏢直線,那麼無論如何都會有一些開銷。謝謝。 – MFlamer
除非使用地圖和擁有的指針讓我能夠並行遍歷...還不確定。 – MFlamer