是否可以在Rust中创建泛型参数类型的实例?
我来自C ++背景,使用模板类型在实际的函数体中创建类型是完全有效的。
我试图在此函数中创建类型为T
的变量,但我不确定如何。
我只是希望能够创建T
类型的对象,加载它,然后将其插入HashMap
:
fn load<T>(&mut self, id: String, path: String)
where T: AssetTrait + 'static
{
// let asset : T = T; this doesn't work?
asset.load(path);
// self.assets.insert(id, Box::new<T>(asset));
}
这是我的所有代码:
trait AssetTrait {
fn load(&self, path: String) {
// Do nothing
// Implement this in child asset object
}
}
struct AssetManager {
assets: HashMap<String, Box<AssetTrait + 'static>>,
}
impl AssetManager {
fn new() -> AssetManager {
let asset_manager = AssetManager { assets: HashMap::new() };
return asset_manager;
}
fn load<T>(&mut self, id: String, path: String)
where T: AssetTrait + 'static
{
// let asset : T = T; this doesn't work?
asset.load(path);
// self.assets.insert(id, Box::new<T>(asset));
}
}
答案 0 :(得分:4)
在C ++中声明类似T asset;
的变量时,假设T
有一个默认构造函数(鸭子类型的编译时版本)。使用没有默认构造函数的类型实例化T
是一个编译器错误,但如果没有这样的实例化,它就没问题。
在Rust中你不能&#34;假设&#34;类型参数支持操作。您必须在类型参数上使用边界指定支持的操作。
那就是说,你必须选择:
在AssetTrait
例如,您可以将load
声明为不带self
参数并返回Self
的关联函数,并调用T::load(path)
来实例化T
}:
use std::collections::HashMap;
trait AssetTrait {
fn load(path: String) -> Self;
}
struct AssetManager {
assets: HashMap<String, Box<AssetTrait + 'static>>,
}
impl AssetManager {
fn new() -> AssetManager {
let asset_manager = AssetManager { assets: HashMap::new() };
return asset_manager;
}
fn load<T>(&mut self, id: String, path: String)
where T: AssetTrait + 'static
{
let asset = T::load(path);
self.assets.insert(id, Box::new(asset));
}
}
使用具有关联函数
等构造函数的预定义特征在Rust中,Default
特征用于此目的:
use std::collections::HashMap;
trait AssetTrait {
fn load(&mut self, path: String);
}
struct AssetManager {
assets: HashMap<String, Box<AssetTrait + 'static>>,
}
impl AssetManager {
fn new() -> AssetManager {
let asset_manager = AssetManager { assets: HashMap::new() };
return asset_manager;
}
fn load<T>(&mut self, id: String, path: String)
where T: Default + AssetTrait + 'static
{
let mut asset = T::default();
asset.load(path);
self.assets.insert(id, Box::new(asset));
}
}