如何拥有动态的Box<dyn Trait<T,S>>?
How to have dynamic Box<dyn Trait<T,S>>?
我有 T 和 S 类型的交易列表,在 运行 时我想获取其详细信息。
如何具有结构的多个泛型类型的特征
我试过的代码如下所述:-
use std::fmt::Debug;
use std::any::Any;
#[derive(Debug)]
struct TransactionSet<T,S>{
pub name: String,
pub key:T,
pub value:S
}
trait Details<T,S>{
fn get_details(&self);
fn get_key(&self)->&T;
fn get_value(&self)->&S;
}
impl<T: Debug, S: Debug> Details<T,S> for TransactionSet<T, S> {
fn get_details(&self) {
println!("{:?} {:?} {:?}",self.name.to_string(),&self.key,&self.value)
}
fn get_key(&self)->&T {
&self.key
}
fn get_value(&self)->&S {
&self.value
}
}
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn get<T: Any>(value: Box<dyn Any>) -> T {
let pv = value.downcast().expect("The pointed-to value must be of type T");
*pv
}
fn main() {
//let mut vec: Vec<Box<dyn NewTrait<T:Debug,S:Debug>>> = Vec::new(); //Not working
// let mut vec: Vec<Box<dyn Details<T: Debug,S: Debug>>> = Vec::new();//Cannot use Details Trait
let vec: Vec<Box<dyn Details<_,_>>> = Vec::new();//Cannot use Details Trait
let a1:TransactionSet<String,String> = TransactionSet { name: String::from("Test1"), key: String::from("name"), value: String::from("vinay") };
let a2:TransactionSet<String,i32> = TransactionSet { name: String::from("Test2"), key: String::from("age"), value: 32_i32 };
let a3 = TransactionSet { name: String::from("Test3"), key: 1_i32, value: 10_u64 };
let a4 = TransactionSet { name: String::from("Test4"), key: String::from("isEligibleToVote"), value: true };
//let a2 = ABC::new( String::from("Test2"), String::from("company"), String::from("supra"));;
vec.push(Box::<TransactionSet<String,String>>::new(a1));
vec.push(Box::<TransactionSet<String,i32>>::new(a2));
vec.push(Box::new(a3));
vec.push(Box::new(a4));
for v in vec.iter() {
v.get_details();
// print_type_of(v);
println!("Key : {:?}", v.get_key());
println!("Value : {:?}", v.get_value());
}
}
有没有其他方法可以解决这个问题?
就像 Vec<Box<dyn Details<?Unknown,?Unknown>>>
如果我删除特征详细信息的通用类型,我不能为它写 getter
你需要使用 dyn 来抽象到你需要的特征。
第一步是为你的特征添加类型,它不需要是通用的:
trait Details {
type Key;
type Value;
fn get_details(&self);
fn get_key(&self) -> &Self::Key;
fn get_value(&self) -> &Self::Value;
}
然后你可以在一些通用的 TransactionSet
上实现特征,其中 bot T
和 S
实现 Debug
:
impl Details for TransactionSet<Box<dyn Debug>, Box<dyn Debug>> {
type Key = Box<dyn Debug>;
type Value = Box<dyn Debug>;
fn get_details(&self) {
println!(
"{:?} {:?} {:?}",
self.name.to_string(),
&self.key,
&self.value
)
}
fn get_key(&self) -> &Self::Key {
&self.key
}
fn get_value(&self) -> &Self::Value {
&self.value
}
}
请注意您的 TransactionSet
类型是 TransactionSet<Box<dyn Debug>, Box<dyn Debug>>
。
这是一个完整的工作示例:
use std::any::Any;
use std::fmt::Debug;
#[derive(Debug)]
struct TransactionSet<T, S> {
pub name: String,
pub key: T,
pub value: S,
}
trait Details {
type Key;
type Value;
fn get_details(&self);
fn get_key(&self) -> &Self::Key;
fn get_value(&self) -> &Self::Value;
}
impl Details for TransactionSet<Box<dyn Debug>, Box<dyn Debug>> {
type Key = Box<dyn Debug>;
type Value = Box<dyn Debug>;
fn get_details(&self) {
println!(
"{:?} {:?} {:?}",
self.name.to_string(),
&self.key,
&self.value
)
}
fn get_key(&self) -> &Self::Key {
&self.key
}
fn get_value(&self) -> &Self::Value {
&self.value
}
}
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn get<T: Any>(value: Box<dyn Any>) -> T {
let pv = value
.downcast()
.expect("The pointed-to value must be of type T");
*pv
}
fn main() {
let mut vec: Vec<Box<dyn Details<Key = _, Value = _>>> = Vec::new(); //Cannot use Details Trait
let a1: TransactionSet<Box<dyn Debug>, Box<dyn Debug>> = TransactionSet {
name: String::from("Test1"),
key: Box::new(String::from("name")),
value: Box::new(String::from("vinay")),
};
let a2: TransactionSet<Box<dyn Debug>, Box<dyn Debug>> = TransactionSet {
name: String::from("Test2"),
key: Box::new(String::from("age")),
value: Box::new(32_i32),
};
// let a3 = TransactionSet { name: String::from("Test3"), key: 1_i32, value: 10_u64 };
// let a4 = TransactionSet { name: String::from("Test4"), key: String::from("isEligibleToVote"), value: true };
vec.push(Box::<TransactionSet<Box<dyn Debug>, Box<dyn Debug>>>::new(
a1,
));
vec.push(Box::<TransactionSet<Box<dyn Debug>, Box<dyn Debug>>>::new(a2));
// vec.push(Box::new(a3));
// vec.push(Box::new(a4));
for v in vec.iter() {
v.get_details();
// print_type_of(v);
println!("Key : {:?}", v.get_key());
println!("Value : {:?}", v.get_value());
}
}
我有 T 和 S 类型的交易列表,在 运行 时我想获取其详细信息。 如何具有结构的多个泛型类型的特征 我试过的代码如下所述:-
use std::fmt::Debug;
use std::any::Any;
#[derive(Debug)]
struct TransactionSet<T,S>{
pub name: String,
pub key:T,
pub value:S
}
trait Details<T,S>{
fn get_details(&self);
fn get_key(&self)->&T;
fn get_value(&self)->&S;
}
impl<T: Debug, S: Debug> Details<T,S> for TransactionSet<T, S> {
fn get_details(&self) {
println!("{:?} {:?} {:?}",self.name.to_string(),&self.key,&self.value)
}
fn get_key(&self)->&T {
&self.key
}
fn get_value(&self)->&S {
&self.value
}
}
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn get<T: Any>(value: Box<dyn Any>) -> T {
let pv = value.downcast().expect("The pointed-to value must be of type T");
*pv
}
fn main() {
//let mut vec: Vec<Box<dyn NewTrait<T:Debug,S:Debug>>> = Vec::new(); //Not working
// let mut vec: Vec<Box<dyn Details<T: Debug,S: Debug>>> = Vec::new();//Cannot use Details Trait
let vec: Vec<Box<dyn Details<_,_>>> = Vec::new();//Cannot use Details Trait
let a1:TransactionSet<String,String> = TransactionSet { name: String::from("Test1"), key: String::from("name"), value: String::from("vinay") };
let a2:TransactionSet<String,i32> = TransactionSet { name: String::from("Test2"), key: String::from("age"), value: 32_i32 };
let a3 = TransactionSet { name: String::from("Test3"), key: 1_i32, value: 10_u64 };
let a4 = TransactionSet { name: String::from("Test4"), key: String::from("isEligibleToVote"), value: true };
//let a2 = ABC::new( String::from("Test2"), String::from("company"), String::from("supra"));;
vec.push(Box::<TransactionSet<String,String>>::new(a1));
vec.push(Box::<TransactionSet<String,i32>>::new(a2));
vec.push(Box::new(a3));
vec.push(Box::new(a4));
for v in vec.iter() {
v.get_details();
// print_type_of(v);
println!("Key : {:?}", v.get_key());
println!("Value : {:?}", v.get_value());
}
}
有没有其他方法可以解决这个问题?
就像 Vec<Box<dyn Details<?Unknown,?Unknown>>>
如果我删除特征详细信息的通用类型,我不能为它写 getter
你需要使用 dyn 来抽象到你需要的特征。
第一步是为你的特征添加类型,它不需要是通用的:
trait Details {
type Key;
type Value;
fn get_details(&self);
fn get_key(&self) -> &Self::Key;
fn get_value(&self) -> &Self::Value;
}
然后你可以在一些通用的 TransactionSet
上实现特征,其中 bot T
和 S
实现 Debug
:
impl Details for TransactionSet<Box<dyn Debug>, Box<dyn Debug>> {
type Key = Box<dyn Debug>;
type Value = Box<dyn Debug>;
fn get_details(&self) {
println!(
"{:?} {:?} {:?}",
self.name.to_string(),
&self.key,
&self.value
)
}
fn get_key(&self) -> &Self::Key {
&self.key
}
fn get_value(&self) -> &Self::Value {
&self.value
}
}
请注意您的 TransactionSet
类型是 TransactionSet<Box<dyn Debug>, Box<dyn Debug>>
。
这是一个完整的工作示例:
use std::any::Any;
use std::fmt::Debug;
#[derive(Debug)]
struct TransactionSet<T, S> {
pub name: String,
pub key: T,
pub value: S,
}
trait Details {
type Key;
type Value;
fn get_details(&self);
fn get_key(&self) -> &Self::Key;
fn get_value(&self) -> &Self::Value;
}
impl Details for TransactionSet<Box<dyn Debug>, Box<dyn Debug>> {
type Key = Box<dyn Debug>;
type Value = Box<dyn Debug>;
fn get_details(&self) {
println!(
"{:?} {:?} {:?}",
self.name.to_string(),
&self.key,
&self.value
)
}
fn get_key(&self) -> &Self::Key {
&self.key
}
fn get_value(&self) -> &Self::Value {
&self.value
}
}
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn get<T: Any>(value: Box<dyn Any>) -> T {
let pv = value
.downcast()
.expect("The pointed-to value must be of type T");
*pv
}
fn main() {
let mut vec: Vec<Box<dyn Details<Key = _, Value = _>>> = Vec::new(); //Cannot use Details Trait
let a1: TransactionSet<Box<dyn Debug>, Box<dyn Debug>> = TransactionSet {
name: String::from("Test1"),
key: Box::new(String::from("name")),
value: Box::new(String::from("vinay")),
};
let a2: TransactionSet<Box<dyn Debug>, Box<dyn Debug>> = TransactionSet {
name: String::from("Test2"),
key: Box::new(String::from("age")),
value: Box::new(32_i32),
};
// let a3 = TransactionSet { name: String::from("Test3"), key: 1_i32, value: 10_u64 };
// let a4 = TransactionSet { name: String::from("Test4"), key: String::from("isEligibleToVote"), value: true };
vec.push(Box::<TransactionSet<Box<dyn Debug>, Box<dyn Debug>>>::new(
a1,
));
vec.push(Box::<TransactionSet<Box<dyn Debug>, Box<dyn Debug>>>::new(a2));
// vec.push(Box::new(a3));
// vec.push(Box::new(a4));
for v in vec.iter() {
v.get_details();
// print_type_of(v);
println!("Key : {:?}", v.get_key());
println!("Value : {:?}", v.get_value());
}
}