出于学习目的,我尝试了这个解决方案,但它不起作用:
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);
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
<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
Run Code Online (Sandbox Code Playgroud)
这样做的正确方法是什么?
目前,+=只定义了原始整数类型; 通常,您需要将其扩展为*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
Run Code Online (Sandbox Code Playgroud)
让我们看一下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;
}
Run Code Online (Sandbox Code Playgroud)
因此Self + RHS产生一个类型的对象<Self as Add<RHS>>::Output.
当您将值存回时*x,计算结果必须为a T; 因此,我们建立了约束的T需要不Add但是.Add<???, Output = T>
那将???是什么?是什么类型的1?它不是通用的; 它的10种已知的基本整数类型之一(isize,i8,i16,i32,i64,usize,u8,u16,u32,u64).这显然是行不通的,因为整型不执行另外较小的类型,默认值对RHS的Self(也就是,其中T: Add表示T: Add<Self>)是所有你可以指望,但1不能是类型T.
解决方案是使用生成值1的通用函数.来自crates.io std::num::One的num箱子里有一个不稳定的,一个稳定的num::One.使用前者需要每晚使用Rust,使用后者需要删除std::,添加extern crate num;并添加num到Cargo.toml依赖项部分.
我们还需要一个Copy绑定,允许*x的*x + 1工作.
#![feature(zero_one)]
use std::ops::Add;
use std::num::One;
fn inc<T: Copy + One + Add<T, Output = T>>(x: &mut T) {
*x = *x + T::one();
}
fn main() {
let mut x: i32 = 10;
let mut y: u8 = 1;
inc(&mut x);
inc(&mut y);
println!("{} {}", x, y);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2665 次 |
| 最近记录: |