如何解决在通用变量中存储嵌套特征实例
如果我有一个具有通用通用类型的“外部”特征(submitUpload = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("filename",this.state.filename);
formData.append("file",this.state.file);
axios({
method: "post",url: "http://localhost:8080/upload",headers: {
"Content-Type": "multipart/form-data",},data: formData,});
};
,下面),那么我可以创建一个具有“内部”特征类型(backend
routes
uploadImg route (where I handle my post)
frontend
folderToStoreIn
)的实例。然后,只要这些值实现嵌套特征(Collection
),我就可以在该实例中使用任何值:
Collection<&dyn Stringable>
但是,如果我同时实现了类型(Stringable
)的外部特征和内部特征,即使该类型的内部类型是fn main() {
let mut vs: &mut Collection<&dyn Stringable> = &mut vec![];
vs.add(&1);
vs.add(&true);
vs.add(&3);
for v in vs.get_all() {
println!("{}",v.string());
}
}
trait Collection<T> {
fn add(&mut self,v: T);
fn get_all(&self) -> &Vec<T>;
}
impl<T> Collection<T> for Vec<T> {
fn add(&mut self,v: T) {
self.push(v)
}
fn get_all(&self) -> &Vec<T> {
&self
}
}
trait Stringable {
fn string(&self) -> String;
}
impl Stringable for i8 {
fn string(&self) -> String {
format!("int({})",self)
}
}
impl Stringable for bool {
fn string(&self) -> String {
format!("bool({})",self)
}
}
,也不能将该类型的值放入Collection<i8>
变量中。第一个(Collection<&dyn Stringable>
)实现第二个(i8
)。下面的代码给出以下错误:
Stringable
代码:
the trait `Collection<&dyn Stringable>` is not implemented for `StaticCollection`
例如,是否可以编写类似fn main() {
let mut vs: &mut Collection<&dyn Stringable> = &mut StaticCollection{};
for v in vs.get_all() {
println!("{}",v.string());
}
}
struct StaticCollection {}
impl Collection<i8> for StaticCollection {
fn add(&mut self,v: i8) {}
fn get_all(&self) -> &Vec<i8> {
&vec![1,2,3]
}
}
的东西,以便可以将impl Collection<&dyn Stringable> for StaticCollection
存储在通用StaticCollection
变量中?
解决方法
这取决于StaticCollection
的实现方式,但是从技术上来说是可能的:
impl<'a> Collection<&'a dyn Stringable> for StaticCollection {
fn add(&mut self,v: &'a dyn Stringable) {
}
fn get_all(&self) -> &Vec<&'a dyn Stringable> {
panic!()
}
}
但是必须使用StaticCollection
个项目创建&dyn Stringable
。
例如(Link to playground):
fn main() {
let mut vs: &mut Collection<&dyn Stringable> = &mut StaticCollection {
v: vec![&0,&1,&2]
};
for v in vs.get_all() {
println!("{}",v.string());
}
}
struct StaticCollection {
v: Vec<&'static dyn Stringable>,}
impl<'a> Collection<&'a dyn Stringable> for StaticCollection {
fn add(&mut self,v: &'a dyn Stringable) {
}
fn get_all(&self) -> &Vec<&'a dyn Stringable> {
&self.v
}
}
请注意,我们在'a
的项的Vec
生命周期中是通用的,但是因为特征(定义已定)需要{{1 }}返回从get_all
借来的&Vec
,则无法“转换” self
。因此,如果您定义Vec
(或StaticCollection { v: Vec<&i8> }
,则Vec<i8>
无法实现(如果没有“泄漏”新的get_all
,这可能不是您想要的)。>
Vec
的整个生存期实际上是:
get_all
警告:fn get_all<'s>(&'s self) -> &'s Vec<&'a ...>
会让您陷入编译器和借用检查器的困境。
您可能还想查看有关探索类似概念的“类型家族”的this blog post。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。