Generics 是否可以从函数返回随机类型的泛型结构
我不确定我想做什么是可能的,但希望有人能想出一个解决办法。我有一个结构:Generics 是否可以从函数返回随机类型的泛型结构,generics,random,rust,Generics,Random,Rust,我不确定我想做什么是可能的,但希望有人能想出一个解决办法。我有一个结构: pub struct VirtType<T> { value: T } pub结构VirtType{ 值:T } 我想生成一个随机类型的随机值来填充这个字段,如下所示: pub fn random_type() -> VirtType { let mut rng = thread_rng(); match rng.gen_range(0,13) { 0 =&g
pub struct VirtType<T> {
value: T
}
pub结构VirtType{
值:T
}
我想生成一个随机类型的随机值来填充这个字段,如下所示:
pub fn random_type() -> VirtType {
let mut rng = thread_rng();
match rng.gen_range(0,13) {
0 => VirtType{value: rng.gen::<bool>()}, //bool
1 => VirtType{value: rng.gen::<u8>()}, //u8
2 => VirtType{value: rng.gen::<u16>()}, //u16
3 => VirtType{value: rng.gen::<u32>()}, //u32
4 => VirtType{value: rng.gen::<u64>()}, //u64
5 => VirtType{value: rng.gen::<u128>()}, //u128
6 => VirtType{value: rng.gen::<i8>()}, //i8
7 => VirtType{value: rng.gen::<i16>()}, //i16
8 => VirtType{value: rng.gen::<i32>()}, //132
9 => VirtType{value: rng.gen::<i64>()}, //i164
10 => VirtType{value: rng.gen::<i128>()}, //i128
11 => { //Array<T>
let t = random_type();
VirtType{value: (0..rng.gen_range(0,10)).map(|_| t.gen_another(&t)).collect()}
}, //Tuple(T)
12 => VirtType{value: (0..rng.gen_range(2,10)).map(|_| random_type()).collect()},
_ => panic!("Invalid number in random_type")
}
}
pub fn random_type()->VirtType{
设mut rng=thread_rng();
匹配发电机量程(0,13){
0=>VirtType{value:rng.gen::()},//bool
1=>VirtType{value:rng.gen::()},//u8
2=>VirtType{value:rng.gen::()},//u16
3=>VirtType{value:rng.gen::()},//u32
4=>VirtType{value:rng.gen::()},//u64
5=>VirtType{value:rng.gen::()},//u128
6=>VirtType{value:rng.gen::()},//i8
7=>VirtType{value:rng.gen::()},//i16
8=>VirtType{value:rng.gen::()},//132
9=>VirtType{value:rng.gen::()},//i164
10=>VirtType{value:rng.gen::()},//i128
11=>{//数组
设t=random_type();
VirtType{value:(0..rng.gen_range(0,10)).map(| | t.gen_另一(&t)).collect()}
},//元组(T)
12=>VirtType{value:(0..rng.gen_range(2,10)).map(| | random_type()).collect(),
_=>死机!(“随机_类型中的无效数字”)
}
}
我不是泛型的高手,而且,我觉得这可能行不通,因为在编译时无法知道返回类型是什么,但这将为我节省大量冗余。关于如何实现这一点有什么想法吗
pub struct VirtType<T> { ... }
pub fn random_type() -> VirtType { ... }
现在,我们将大量构造它们,因此让我们定义一个帮助器方法,以避免编写VirtType{value:Box::new(…)}
impl VirtType {
fn new<T: 'static + Debug + Sized>(value: T) -> Self {
VirtType { value: Box::new(value) }
}
}
现在,还有一些问题案例
11 => { //Array<T>
let t = random_type();
VirtType{value: (0..rng.gen_range(0,10)).map(|_| t.gen_another(&t)).collect()}
},
这根本行不通,至少如果你想构造一个真正的元组:每个可能的元组长度都是不同的类型。您需要返回一个向量,如果您想区分异构(元组)和异构(向量/数组),请使用某种显式标记进行区分。这确实是不可能的,因为
->VirtType
忽略了
(根据匹配的分支不同,这可能不一样)。但是,假设这是可能的,您打算如何使用生成的VirtType
?在不知道确切意图的情况下,我想一个enum
可能会有所帮助。这是不可能的,不。如果你提供更多关于你为什么这样做的背景,可能有人能够提出一个解决方案来实现你的基本目标。我同意,你所要求的绝对是不可能的,Rust函数只能返回一个类型,因此您必须使用enum
或使用某种类型擦除技巧(以及向下转换或动态调度)来操作它,但了解这将是什么用途,以及您实际尝试实现的目标将非常有用。谢谢大家。我也这么想。我正在写一个随机生成变量的代码,这些变量可以很容易地转换成文本。我最初使用的是enum,但这导致了大量的匹配语句,最终都变得很草率。我目前正在尝试将代码转换为使用structs+traits而不是enum,但我一直遇到问题。这里有一个线程详细介绍了主要问题并寻求帮助:t.gen\u另一个(&t)
是在创建最小示例oops时犯的错误。不过你的用法是正确的。是的,虚拟的“元组”只是构造了一个随机病毒类型的向量。你在这里说的话帮了大忙,非常感谢。我现在已经达到了90%的目标。最后一个问题是,您知道如何为self.value中包含的每种类型设置自定义调试/显示impl吗?我的最终目标是让VirtType在debug中打印时显示类型表示,在display中打印时显示值(例如debug:[u8;4]display:[33,8,25,4]),如果您想了解更多关于我的意思的上下文,这就是我试图浓缩的内容down@NoNameJones您必须使用自己的格式化方法(就像那些在Debug
和Display
上的)你在dyn
中使用的自定义特性,如果你遵循我的答案,然后你可以让VirtType
同时执行Debug
和Display
,并将格式委托给你的自定义方法。哦,太好了!非常感谢你
pub fn random_type() -> VirtType {
let mut rng = thread_rng();
match rng.gen_range(0,11) {
0 => VirtType::new(rng.gen::<bool>()),
1 => VirtType::new(rng.gen::<u8>()),
2 => VirtType::new(rng.gen::<u16>()),
3 => VirtType::new(rng.gen::<u32>()),
...
11 => { //Array<T>
let t = random_type();
VirtType{value: (0..rng.gen_range(0,10)).map(|_| t.gen_another(&t)).collect()}
},
12 => VirtType{value: (0..rng.gen_range(2,10)).map(|_| random_type()).collect()},