如何在Rust中使用unsized类型

rdlzhqv9  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(189)

我读了Sized trait https://doc.rust-lang.org/std/marker/trait.Sized.html的文档。
我发现了这段代码:

struct Bar<T: ?Sized>(T);
struct BarUse(Bar<[i32]>);

然后我尝试了许多不同的方法(如下所示)来创建一个BarUse对象,但是总是不成功。

struct Bar<T: ?Sized>(T);
struct BarUse(Bar<[i32]>);

fn main() {
    let bar = Bar([1, 2, 3]);
    let bar_use = BarUse(bar);
}

有人能给我看一下可以获取BarUse对象的代码吗(引用和指针也很好)?

z0qdvdin

z0qdvdin1#

未调整大小的类型总是必须在一些间接性之后。例如,Box

struct Bar<T: ?Sized>(T);
struct BarUse(Box<Bar<[i32]>>);

fn main() {
    let bar = Bar([1, 2, 3]);
    let bar_use = BarUse(Box::new(bar));
}

但是,如果我们想保持BarUse不变,并将BarUse装箱,那么不幸的是,我们不能这样做。
自定义未调整大小的类型只支持一半;它们是可以 * 写 * 的,但它们几乎不可能 * 示例化 *,除非它们是泛型的(除非是不安全的代码)。

jdg4fx2g

jdg4fx2g2#

在Rust中,?Sized trait bound与trait对象一起使用,以指示实现trait的类型可以是动态大小的类型。然而,在你的代码中,你试图使用?使用泛型类型参数调整大小,这不是有效的用法。为了实现你的目标,你应该使用trait对象,而不是试图直接创建一个带有动态大小类型的BarUse示例。下面是修改代码的方法

struct Bar<T: ?Sized>(T);
trait MyTrait {
    fn some_function(&self);
}
impl MyTrait for [i32] {
    fn some_function(&self) {
        // Do something with the dynamically sized type.
        println!("{:?}", self);
    }
}
struct BarUse {
    bar: Bar<dyn MyTrait>,
}
fn main() {
    let bar = Bar([1, 2, 3] as [i32; 3]); // Convert to a fixed-size array
    let bar_use = BarUse { bar: bar };
    
    // You can now call methods on the trait object.
    bar_use.bar.0.some_function();
}

在此修改后的代码中:
我们用some_function方法定义了一个trait MyTrait。
我们为[i32]实现MyTrait,为i32的数组提供trait的实现。
我们没有尝试直接创建一个具有动态大小类型的BarUse示例,而是创建一个具有trait对象Bar的Bar。这允许我们通过trait对象处理动态大小的类型。
在main函数中,我们创建了一个Bar示例,并使用它来初始化一个BarUse示例。然后,您可以在BarUse中调用trait对象上的方法,如示例所示。

相关问题