gpt4 book ai didi

rust - dyn MyTrait的大小无法在采用self的方法中静态确定。

转载 作者:行者123 更新时间:2023-12-03 11:41:37 25 4
gpt4 key购买 nike

我正在创建HashMap<u64, Box<dyn MyTrait>>。我可以创建HashMap并插入一个实现MyTrait的结构,但是当我检索MyTrait并尝试使用它时,编译器向我提示:

error[E0161]: cannot move a value of type dyn MyTrait: the size of dyn MyTrait cannot be statically determined
我的印象是,特征包含两个指针,一个指向vtable,另一个指向对象数据。因此,包括 MyTrait在内的任何特征的大小都应为 2 * pointer_size。此外,对象数据指针指向大小已知的 MyStruct。显然,我的理解是错误的,但我不知道为什么。
这是我的代码:
use std::collections::HashMap;

fn main() {
let mut hm: HashMap<u64, Box<dyn MyTrait>> = HashMap::new();
hm.insert(0, Box::new(MyStruct{num: 0}));
match hm.get(&(0 as u64)) {
Some(r) => {
r.my_fun();
}
None => { println!("not found");}
}
}

pub trait MyTrait {
fn my_fun(self);
}

struct MyStruct {
num: u64,
}

impl MyTrait for MyStruct {
fn my_fun(self) {
println!("num is {}", self.num);
return
}
}

最佳答案

当您在MyTrait中将方法声明为fn my_fun(self);时,这将创建一个通过值而不是通过引用使用self参数的方法。在Rust中,大多数值都没有隐式克隆(对于那些值,它仅支持逐位直接复制)。
通常,按值传递参数会导致其被移动,此后其旧位置不再有效,并且以某种方式变为无效行为。 (尽管这不会发生是由编译器强制执行的。)
错误并不是说您不能在Box<dyn MyTrait>的值中包含HashMap,而是您不能将dyn MyTrait&Box<dyn MyTrait>调用中获得的hm.get引用中移出。即使在那里有大小类型而不是无大小类型,这仍然是不可能的,因为除非类型为Copy,否则您不能将值从共享引用的后面移出。 (在这种情况下,它是完全复制而不是移动的。)
最有可能的是,您想使用fn my_fun(&self),它通过引用而不是值来接受self参数。
如果要更改函数中的值,则应声明函数fn my_fun(&mut self),然后将hm.get替换为hm.get_mut,以便您可以对MyStruct进行可变引用。
如果确实需要通过值而不是引用来获取self参数,则可以编写fn my_fun(self: Box<Self>)声明self参数是一个装箱的值,然后将hm.get行更改为hm.remove。顾名思义,这将使值不再在哈希图中可访问。

关于rust - dyn MyTrait的大小无法在采用self的方法中静态确定。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63766721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com