Rust 不使用';我不在乎拥有它
我经常想在Rust中定义递归数据类型。我们需要某种程度的间接寻址,以避免使用大小无限的类型。经典的解决方案是使用Rust 不使用';我不在乎拥有它,rust,ownership,borrowing,Rust,Ownership,Borrowing,我经常想在Rust中定义递归数据类型。我们需要某种程度的间接寻址,以避免使用大小无限的类型。经典的解决方案是使用Box(): 但它失败了 错误[E0275]:评估需求的溢出'IntList` =注意:必需,因为它出现在类型“std::borrow::Cow”中>` =注意:枚举变量的任何字段都不能具有动态大小的类型 我创建了一种类似于Cow的数据类型,我称之为Cowish。如果已经有类似的事情发生,请告诉我 pub enum Cowish<'a, T, O> where T:
Box
():
但它失败了
错误[E0275]:评估需求的溢出'IntList`
=注意:必需,因为它出现在类型“std::borrow::Cow”中>`
=注意:枚举变量的任何字段都不能具有动态大小的类型
我创建了一种类似于Cow
的数据类型,我称之为Cowish
。如果已经有类似的事情发生,请告诉我
pub enum Cowish<'a, T, O>
where
T: 'a,
{
Borrowed(&'a T),
Owned(O),
}
impl<'a, T, O> Borrow<T> for Cowish<'a, T, O>
where
T: 'a,
O: Borrow<T>,
{
fn borrow(&self) -> &T {
match self {
Borrowed(b) => b,
Owned(o) => o.borrow(),
}
}
}
impl<'a, T, O> Cowish<'a, T, O>
where
T: ToOwned<Owned=O> + 'a,
O: Borrow<T>,
{
pub fn into_owned(self) -> O {
match self {
Borrowed(b) => b.to_owned(),
Owned(o) => o,
}
}
}
pub enum Cowish借用Cowish&T{
匹配自我{
借用(b)=>b,
拥有(o)=>o.借用(),
}
}
}
恳求
哪里
T:Toowed+a,
O:借,
{
pub fn in_own(self)->O{
匹配自我{
借来的(b)=>b.给拥有的(),
拥有(o)=>o,
}
}
}
利用它,我可以做我想做的事:
enum IntList<'a> {
Empty,
Cons(i32, Cowish<'a, IntList<'a>, Box<IntList<'a>>>),
}
enum IntList>>),
}
可以找到一个更大的例子。这可能太旧了,但只是为了记录,如果您想制作一个链表,可以使用
std::rc::rc
。它就像Box
,但是可以对单个对象有多个引用。唯一需要注意的是,一旦列表包含在Rc中,就不能对其进行变异。以下是来自以下方面的示例:
枚举列表{
Cons(i32,Rc),
无
}
使用板条箱::列表:{Cons,Nil};
使用std::rc::rc;
fn main(){
设a=Rc::new(Cons(5,Rc::new)(Cons(10,Rc::new(Nil '));//[10,5]
设b=Cons(3,Rc::clone(&a));/[10,5,3]
设c=Cons(4,Rc::clone(&a));/[10,5,4]
}
错误消息令人困惑,但您正在尝试创建一种无限大小的类型。请参见将Cow
包装在框中是解决此问题的一种方法。我知道无限大小的类型是不好的,但我的理解是Cow>
代表Box@JJW5432Cow
不装箱。它将是intlist,那么为什么它会为字符串设置“框”?它是&str
或字符串
,大致是框
(如果不是这样,请纠正我)。这就是我想要的行为,或者是一个盒子或者是一个盒子“如果已经有类似的东西了,请让我知道!”-这不完全一样,但是你可以使用。结果可能是这样的:
#[derive(Clone)]
enum IntList<'a> {
Empty,
Cons(i32, Cow<'a, IntList<'a>),
}
pub enum Cowish<'a, T, O>
where
T: 'a,
{
Borrowed(&'a T),
Owned(O),
}
impl<'a, T, O> Borrow<T> for Cowish<'a, T, O>
where
T: 'a,
O: Borrow<T>,
{
fn borrow(&self) -> &T {
match self {
Borrowed(b) => b,
Owned(o) => o.borrow(),
}
}
}
impl<'a, T, O> Cowish<'a, T, O>
where
T: ToOwned<Owned=O> + 'a,
O: Borrow<T>,
{
pub fn into_owned(self) -> O {
match self {
Borrowed(b) => b.to_owned(),
Owned(o) => o,
}
}
}
enum IntList<'a> {
Empty,
Cons(i32, Cowish<'a, IntList<'a>, Box<IntList<'a>>>),
}
enum List {
Cons(i32, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
use std::rc::Rc;
fn main() {
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); // [10, 5]
let b = Cons(3, Rc::clone(&a)); // [10, 5, 3]
let c = Cons(4, Rc::clone(&a)); // [10, 5, 4]
}