Multiple return types from a method
(1个答案)
Idiomatic way of returning multiple types in Rust [duplicate]
(2个答案)
在5个月前关闭。
我不确定我想做什么,但希望有人提出解决方案。我有一个结构:
pub struct VirtType<T> {
value: 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 struct VirtType<T> { ... }
pub fn random_type() -> VirtType { ... }
最基本的问题,首先应该考虑的“这不能工作”是您不能忽略这样的类型参数。
您可以做的是通过动态调度消除参数。请注意,这样做时,您需要指定要对值进行的处理,以作为特征。您想“将它们转换为文本”,所以我们使用
Debug
,但是请注意,您可能很想使用自定义特征。
pub struct VirtType {
value: Box<dyn Debug>
}
现在,我们将大量地构建它们,因此让我们定义一个辅助方法,以避免过多地编写
VirtType { value: Box::new(...) }
:
impl VirtType {
fn new<T: 'static + Debug + Sized>(value: T) -> Self {
VirtType { value: Box::new(value) }
}
}
现在,如果这样编写,
random_type()
将进行编译:
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()}
},
要定义
gen_another
,我假设它应该产生更多相同类型的值(我不确定为什么要同时将
t
作为自身和参数),您需要使用自定义特征而不是
Debug
,并给出该特性返回
Self
的方法。但是,您实际上不能通过动态调度(“特征对象”)来做到这一点!不允许返回未装箱的动态类型的值。
您有两种选择:
构造一个VirtType
实例的向量(但是您不知道它们都是相同的类型)。
在特征中,编写一个返回包含值向量的VirtType
的方法。
12 => VirtType{value: (0..rng.gen_range(2,10)).map(|_| random_type()).collect()},
这一点根本行不通,至少在您打算构造一个真正的元组的情况下:每个可能的元组长度都是不同的类型。您将需要返回一个向量,并且如果要区分异构(元组)和同类(向量/数组),请使用某种显式标记来实现。
我是一名优秀的程序员,十分优秀!