尝试无堆链接列表时缺少什么?
我的目标是获取以下代码以在堆栈上生成序列[1、2、3],然后将这些值打印在单独的行上,而不使用Box
或需要堆的任何其他内容或std
或malloc
。
我浏览了https://rust-unofficial.github.io/too-many-lists,但是所有“好”列表似乎都取决于Rc
,Box
等。
heapless
crate整洁,但需要事先知道列表的大小。
我的Google-fu不够强大,无法找到很多帮助。任何指针将不胜感激。但是,这就是我的想法:
struct Node<'a, T> {
value: T,
next: Option<&'a Node<'a, T>>
}
struct List<'a, T> {
head: Option<&'a Node<'a, T>>,
tail: Option<&'a Node<'a, T>>
}
impl<'a, T> List<'a, T> {
fn new() -> Self {
Self {
head: None,
tail: None
}
}
fn push(self, value: T) ->Self {
unimplemented!(); // What's missing here?
}
}
struct Iter<'a, T> {
next: Option<&'a Node<'a, T>>
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
match self.next.take() {
Some(next) => {
self.next = next.next;
Some(&next.value)
},
None => None
}
}
}
impl<'a, T> IntoIterator for List<'a, T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
next: self.head
}
}
}
fn main() {
let list = List::new();
let list = list.push(1);
let list = list.push(2);
let list = list.push(3);
for item in list {
println!("{}", item);
}
}
如您所见,我在尝试实现List.push
时遇到了困难。
答案 0 :(得分:1)
在不知道其大小(或至少其大小的上限)的情况下分配堆栈中的东西将对圆进行平方运算,将无法正常工作。您可以让编译器为您确定大小,但这差不多。原因很简单:堆栈分配可能不会失败,并且编译器必须确保所有内容都适合。
如果您想继续坚持使用push(T)
签名,那么只取值Matt Thomas的答案就可以了。
这是我的问题,它避免了构建嵌套类型:
struct Node<'a, T> {
value: T,
next: Option<&'a Node<'a, T>>,
}
impl<'a, T> Node<'a, T> {
pub fn new(value: T, next: Option<&'a Self>) -> Self {
Node { value, next }
}
pub fn iter(&'a self) -> Iter<'a, T> {
Iter {
current: Some(self),
}
}
}
struct Iter<'a, T> {
current: Option<&'a Node<'a, T>>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
match self.current {
Some(Node { value, next }) => {
self.current = *next;
Some(value)
}
None => None,
}
}
}
fn main() {
// Allocation of the Nodes directly on the stack,
// not inside a push method. <= Solves lifetime issues
// Reversed order solves mutability issues.
let three = Node::new(3, None);
let two = Node::new(2, Some(&three));
let one = Node::new(1, Some(&two));
for item in one.iter() {
println!("{}", item)
}
}
答案 1 :(得分:0)
这里是一个无栈的堆栈,可以完成OP中所述的目标:
#[derive(Debug)]
struct Cons<T, U>(T, U);
#[derive(Debug)]
struct MyOption<T>(Option<T>);
trait Push<T>: Sized {
fn push(self, value: T) -> Cons<Self, T>;
}
impl<T, U> Push<U> for Cons<T, U> {
fn push(self, value: U) -> Cons<Self, U> {
Cons(self, value)
}
}
impl<T> Push<T> for T {
fn push(self, value: T) -> Cons<Self, Self> {
Cons(self, value)
}
}
impl<T: Iterator<Item = U>, U> Cons<T, MyOption<U>> {
fn next(&mut self) -> Option<U> {
match (self.1).0.take() {
Some(u) => Some(u),
None => self.0.next()
}
}
}
impl<T> Iterator for Cons<MyOption<T>, MyOption<T>> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match (self.1).0.take() {
Some(t) => Some(t),
None => (self.0).0.take()
}
}
}
impl<T: Iterator<Item = U>, U> Iterator for Cons<Cons<T, MyOption<U>>, MyOption<U>> {
type Item = U;
fn next(&mut self) -> Option<Self::Item> {
match (self.1).0.take() {
Some(u) => Some(u),
None => self.0.next()
}
}
}
impl<T> Iterator for MyOption<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.take()
}
}
fn create_stack() -> impl Iterator<Item = i32> + core::fmt::Debug {
MyOption(Some(0))
.push(MyOption(Some(1)))
.push(MyOption(Some(2)))
.push(MyOption(Some(3)))
.push(MyOption(Some(4)))
}
fn main() {
let stack = create_stack();
println!("Here's the stack:");
println!("{:?}", stack);
println!("Here are the items in reverse order");
for item in stack {
println!("{}", item);
}
}
输出:
Here's the stack: Cons(Cons(Cons(Cons(MyOption(Some(0)), MyOption(Some(1))), MyOption(Some(2))), MyOption(Some(3))), MyOption(Some(4))) Here are the items in reverse order 4 3 2 1 0
stack = stack.push(...)
(因为stack.push(...)
返回不同的类型)Drop
的行为。我想这将是递归的,并且对于大堆栈来说会很麻烦Iterator
结构来容纳Cons
类型的Option
?并且可以多次迭代的方法吗?也许.push()
都可能会复制self
(这与Copy
特征不同,但在Rust中,Rust可以在幕后做memcpy
作为所有权移动以使事情保持整洁”