在Rust中,可以创建只有一个字段的元组结构,如下所示:
struct Centimeters(i32);
Run Code Online (Sandbox Code Playgroud)
我想这样做基本的算术有Centimeters没有与模式匹配,每次提取他们的"内心"的价值观,并没有实现Add,Sub...特点和运算符重载.
我想做的是:
let a = Centimeters(100);
let b = Centimeters(200);
assert_eq!(a + a, b);
Run Code Online (Sandbox Code Playgroud) 我最初的问题是将不同类型的元组转换为字符串.在Python中,这将是这样的:
>> a = ( 1.3, 1, 'c' )
>> b = map( lambda x: str(x), a )
['1.3', '1', 'c']
>> " ".join(b)
'1.3 1 c"
Run Code Online (Sandbox Code Playgroud)
然而,Rust不支持元组上的映射 - 仅支持类似矢量的结构.显然,这是因为能够将不同类型打包成元组并且缺少函数重载.此外,我找不到在运行时获取元组长度的方法.所以,我想,需要一个宏来进行转换.
首先,我尝试匹配元组的头部,例如:
// doesn't work
match some_tuple {
(a, ..) => println!("{}", a),
_ => ()
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题:
我正在尝试自己实现大整数(仅用于教育)。该实现按数据类型通用:
struct LongNum<T>
where T: Integer + MulAssign + CheckedMul + CheckedAdd + Copy + From<u8>
{
values: Vec<T>,
powers: Vec<u8>,
radix: u8,
}
Run Code Online (Sandbox Code Playgroud)
问题在于,我需要在所有impls中对T重复此冗长的约束。太麻烦了
我可以结合这些约束来做出自己的特征,如下所示:
trait LongNumValue: Integer + MulAssign + CheckedMul + CheckedAdd + Copy + From<u8> {}
struct LongNum<T: LongNumValue>
{
values: Vec<T>,
powers: Vec<u8>,
radix: u8,
}
Run Code Online (Sandbox Code Playgroud)
但是在这种情况下,我必须为此LongNumValue特性添加impls到可以在LongNum中使用的所有类型:
impl LongNumValue for u8 {}
impl LongNumValue for u16 {}
impl LongNumValue for u32 {}
...
Run Code Online (Sandbox Code Playgroud)
这意味着,如果我不向此impls列表中添加某种类型,则即使该类型传递了所有约束,我的板条箱用户也将无法将其用于LongNum。
有什么方法可以避免编写长时间的重复成本损失,而又不会给用户增加不必要的限制?
我有这样一个特质:
trait Foo {
fn do_something(self) -> Self;
}
Run Code Online (Sandbox Code Playgroud)
我想为一个元组实现此特征,该元组可能具有任意数量的实现此特征的元素。
impl<T> Foo for (T, T) where T: Foo {
fn do_something(self) -> Self {
let (t0, t1) = self;
(t0.do_something(), t1.do_something())
}
}
impl<T> Foo for (T, T, T) where T: Foo {
fn do_something(self) -> Self {
let (t0, t1, t2) = self;
(t0.do_something(), t1.do_something(), t2.do_something())
}
}
// and so on...
Run Code Online (Sandbox Code Playgroud)