是否可以在 Rust 中创建泛型参数类型的实例?
我来自 C++ 背景,使用模板类型在实际函数体中创建类型是完全有效的。
我正在尝试T在此函数中创建一个具有类型的变量,但我不确定如何。
我只想能够创建一个 type 的对象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));
}
Run Code Online (Sandbox Code Playgroud)
这是我的所有代码:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
在 C++ 中,当您声明一个变量时,就像T asset;您假设的那样T具有默认构造函数(鸭子类型的编译时版本)。T使用没有默认构造函数的类型实例化是编译器错误,但如果没有发生这样的实例化也没关系。
在 Rust 中,您不能“假设”类型参数支持操作。您必须在类型参数上指定受支持的操作。
也就是说,您必须选择:
定义您自己的构造函数,如关联函数 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));
}
}
Run Code Online (Sandbox Code Playgroud)
使用具有类似关联函数的构造函数的预定义特征
在 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));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2473 次 |
| 最近记录: |