I have a struct that has a field where the type is generic, but to create new records of this struct does not let me copy the generic types into rust

huangapple go评论66阅读模式
英文:

I have a struct that has a field where the type is generic, but to create new records of this struct does not let me copy the generic types into rust

问题

以下是您提供的Rust代码的翻译部分:

use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;

pub struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
    length: u32
}
impl<T: Display> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        LinkedList { head: None, length: 0 }
    }

    pub fn length(&self) -> u32 {
        return self.length;
    }

    pub fn add(&mut self, value: T) {

        match &self.head {
            Some(p) => {
                self.head = Node::new(value, Some(p.clone()));
            },
            None => self.head = Node::new(value, None),
        }

        self.length += 1;
    }
}


struct Node<T> {
    value: T,
    next: Option<Box<Node<T>>>
}
impl<T> Node<T> {
    fn new(value: T, next: Option<Box<Node<T>>>) -> Option<Box<Node<T>>> {
        Some(Box::new(Node { value: value, next: next }))
    }

    fn function(pointer: &Box<Node<T>>) -> Option<Box<Node<T>>> {
        let value = &pointer.value;
        let next = pointer.next.clone();
        Node::new(value.clone(), next)
    }
}
impl<T: Display> Display for Node<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(f, "{}", self.value)
    }
}

fn main() {
    let mut list: LinkedList<u32> = LinkedList::new();
    list.add(5);
    list.add(7);
    list.add(18);
}

这是您提供的Rust代码的翻译部分。如果您有任何关于代码的问题或需要进一步的解释,请随时提问。

英文:
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;

pub struct LinkedList&lt;T&gt; {
    head: Option&lt;Box&lt;Node&lt;T&gt;&gt;&gt;,
    lenght: u32
}
impl&lt;T: Display&gt; LinkedList&lt;T&gt; {
    pub fn new() -&gt; LinkedList&lt;T&gt; {
        LinkedList { head: None, lenght: 0 }
    }

    pub fn lenght(&amp;self) -&gt; u32 {
        return self.lenght;
    }

    pub fn add(&amp;mut self,value: T) {

        match &amp;self.head {
            Some(p) =&gt; {
                self.head = Node::new(value, Some(*p));
            },
            None =&gt; self.head = Node::new(value, None),
        }

        self.lenght += 1;
    }
}


struct Node&lt;T&gt; {
    value: T,
    next: Option&lt;Box&lt;Node&lt;T&gt;&gt;&gt;
}
impl&lt;T&gt; Node&lt;T&gt; {
    fn new(value: T,next: Option&lt;Box&lt;Node&lt;T&gt;&gt;&gt;) -&gt; Option&lt;Box&lt;Node&lt;T&gt;&gt;&gt; {
        Some(Box::new(Node { value: value,next: next}))
    }

    fn function(pointer: &amp;Box&lt;Node&lt;T&gt;&gt;) -&gt; Option&lt;Box&lt;Node&lt;T&gt;&gt;&gt; {
        let value = pointer.value;
        let next = pointer.next;
        Node::new(value, next)
    }
}
impl&lt;T: Display&gt; Display for Node&lt;T&gt; {
    fn fmt(&amp;self, f: &amp;mut Formatter&lt;&#39;_&gt;) -&gt; Result {
        write!(f,&quot;{}&quot;,self.value)
    }
}

fn main() {
    let mut list: LinkedList&lt;u32&gt; = LinkedList::new();
    list.add(5);
    list.add(7);
    list.add(18);
}

I am learning rust and so I am trying to implement LinkedLists as an exercise to understand how the language works, but I am stuck.

I cannot add the elements because I cannot enter the current head for the new element as the successor

I think I'm having problems with the ownership rules, I've tried to read the documentation, but I don't understand how to overcome this problem

I would like somehow once I add an item to the list to have the successor be the current head and the head swapped with the new one

答案1

得分: 2

Linked list在Rust中不太容易或高效,这已经成为某种

话虽如此,你的LinkedList::add()函数很容易修复。问题在于你将self作为可变引用,因此里面的一切都被借用了,但你需要拥有该值才能将其插入到新创建的节点的尾部。这可能是编译器试图告诉你的问题。

由于你不能拥有一个已借用的值,解决方案是将其"窃取",即用虚拟值替换它。幸运的是,你的值在一个Option中,因此有一个函数可以做到:Option::take()

    pub fn add(&mut self, value: T) {
        match self.head.take() {
            Some(p) => {
                self.head = Node::new(value, Some(p));
            },
            None => self.head = Node::new(value, None),
        }
        self.length += 1;
    }

Node::function()中仍然存在错误,但我不知道它应该做什么。还有一些非习惯用法的Rust代码,例如要求:Display,但没有使用Display,或者从Node::new()返回Option<Node>(),但没有其他导致编译失败的问题。

英文:

Linked list are not particularly easy or performant in Rust, that has become some kind of meme.

That said your LinkedList::add() function is easy to fix. The issue is that you are taking self as a mutable reference, so everything inside is borrowed, but you need ownership of the value to be able to insert it into the tail of the newly created node. That is what the compiler is probably trying to tell you.

Since you cannot own a borrowed value, the solution is to steal it, that is replace it with a dummy value. Fortunately your value is inside an Option so there is a function for that: Option::take():

    pub fn add(&amp;mut self, value: T) {
match self.head.take() {
Some(p) =&gt; {
self.head = Node::new(value, Some(p));
},
None =&gt; self.head = Node::new(value, None),
}
self.lenght += 1;
}

There is still an error in Node::function() but I don't know that that is supposed to do. Also there are a few non-idiomatic Rust here and there, such as the requirement for : Display when no Display is being used, or returning Option&lt;Node&gt;() from a Node::new(), but nothing else that fails the compilation.

huangapple
  • 本文由 发表于 2023年5月14日 01:27:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244065.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定