在我努力学习生锈的过程中,我试图找到最好的方法来打印生锈的结构单链表。这是我的代码:
struct SList {
n: int,
next: Option<Box<SList>>
}
fn print_slist(mut l: &SList) {
print!("{}", l.n);
loop {
match l.next {
Some(ref next) => { print!(" -> {}", next.n); l = &(**next); },
None => { break; }
}
}
println!("");
}
fn main() {
let sl1 = SList { n: 11, next: Some(box SList { n: 22, next: Some(box SList { n: 33, next: None })})};
print_slist(&sl1);
}
我确信这可以用更好的方式完成,我想知道它们。除此之外,我关注&(**next)
部分。它是否为下一个SList
创建了不必要的副本?
答案 0 :(得分:3)
您的工作正常,next
的类型为&Box<SList>
,因此&**next
的类型为&SList
。
然而,您可以通过取消引用模式中的框并立即获取&SList
来整理它。
Some(box ref next) => {
print!(" -> {}", next.n);
l = next;
},
我还建议用迭代器来编写这样的东西。同时实现std::fmt::Show
而不是编写单独的函数。
以下是迭代和实现Show
的示例实现:
use std::fmt;
struct SList {
n: int,
next: Option<Box<SList>>
}
struct SListIter<'a> {
current: Option<&'a SList>,
}
impl SList {
fn iter<'a>(&'a self) -> SListIter<'a> {
SListIter {
current: Some(self),
}
}
}
impl<'a> Iterator<int> for SListIter<'a> {
fn next(&mut self) -> Option<int> {
self.current.map(|current| {
let value = current.n;
self.current = match current.next {
Some(box ref next) => Some(next),
None => None
};
value
})
}
}
impl fmt::Show for SList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut first = true;
for value in self.iter() {
if !first {
try!(write!(f, " -> "));
}
try!(write!(f, "{}", value));
first = false;
}
Ok(())
}
}
fn main() {
let sl1 = SList { n: 11, next: Some(box SList { n: 22, next: Some(box SList { n: 33, next: None })})};
println!("{}", sl1);
}