出于学习目的,我尝试了这个解决方案,但是it does not work:
use std::ops::Add;
fn inc<T: Add>(x:&mut T) {
*x += 1;
}
fn main() {
let mut x:i32 = 10;
let mut y:u8 = 1;
inc(&mut x);
inc(&mut y);
println!("{} {}", x, y);
}
错误讯息:
<anon>:4:5: 4:7 error: binary assignment operation `+=` cannot be applied to types `T` and `_` [E0368]
<anon>:4 *x += 1;
^~
<anon>:4:5: 4:7 help: see the detailed explanation for E0368
error: aborting due to previous error
这样做的正确方法是什么?
答案 0 :(得分:5)
目前,+=
仅在原始整数类型上定义;通常,您需要将其扩展为*x = *x + 1;
。这样就会发现更多问题:
<anon>:4:15: 4:16 error: mismatched types:
expected `T`,
found `_`
(expected type parameter,
found integral variable) [E0308]
<anon>:4 *x = *x + 1;
^
<anon>:4:10: 4:16 error: mismatched types:
expected `T`,
found `<T as core::ops::Add>::Output`
(expected type parameter,
found associated type) [E0308]
<anon>:4 *x = *x + 1;
^~~~~~
error: aborting due to 2 previous errors
让我们看看Add
特征的定义:
pub trait Add<RHS = Self> {
/// The resulting type after applying the `+` operator
type Output;
/// The method for the `+` operator
fn add(self, rhs: RHS) -> Self::Output;
}
因此Self + RHS
会生成<Self as Add<RHS>>::Output
类型的对象。
当您将值存储回*x
时,计算结果必须为T
;因此我们确定T
上的界限不需要Add
而是Add<???, Output = T>
。
那么???
会是什么? 1
的类型是什么?它不是通用的;它是十种已知的原始整数类型之一(isize
,i8
,i16
,i32
,i64
,usize
,{{1} },u8
,u16
,u32
)。这显然不起作用,因为整数类型没有实现较小类型的添加 - u64
RHS
的默认值(即Self
表示T: Add
})是您可以依赖的所有内容,但T: Add<Self>
不能是1
类型。
解决方案是使用生成值 1 的通用函数。 std::num::One
中存在一个不稳定,而来自crates.io,T
的{{1}}包中有一个稳定的。使用前者需要每晚使用Rust,使用后者需要删除num
,添加num::One
并将std::
添加到Cargo.toml依赖项部分。
我们还需要extern crate num;
一定允许num
Copy
工作。
*x