Léo*_*lli 7 generics int traits rust
我想实现一个函数来计算任何泛型类型的整数中的位数.这是我提出的代码:
extern crate num;
use num::Integer;
fn int_length<T: Integer>(mut x: T) -> u8 {
if x == 0 {
return 1;
}
let mut length = 0u8;
if x < 0 {
length += 1;
x = -x;
}
while x > 0 {
x /= 10;
length += 1;
}
length
}
fn main() {
println!("{}", int_length(45));
println!("{}", int_length(-45));
}
Run Code Online (Sandbox Code Playgroud)
这是编译器输出
error[E0308]: mismatched types
--> src/main.rs:5:13
|
5 | if x == 0 {
| ^ expected type parameter, found integral variable
|
= note: expected type `T`
found type `{integer}`
error[E0308]: mismatched types
--> src/main.rs:10:12
|
10 | if x < 0 {
| ^ expected type parameter, found integral variable
|
= note: expected type `T`
found type `{integer}`
error: cannot apply unary operator `-` to type `T`
--> src/main.rs:12:13
|
12 | x = -x;
| ^^
error[E0308]: mismatched types
--> src/main.rs:15:15
|
15 | while x > 0 {
| ^ expected type parameter, found integral variable
|
= note: expected type `T`
found type `{integer}`
error[E0368]: binary assignment operation `/=` cannot be applied to type `T`
--> src/main.rs:16:9
|
16 | x /= 10;
| ^ cannot use `/=` on type `T`
Run Code Online (Sandbox Code Playgroud)
我明白问题来自于我在函数中使用常量,但我不明白为什么特征规范Integer
没有解决这个问题.
它的文档Integer
说它实现了PartialOrd
等特征Self
(我假设参考Integer
).通过使用也实现Integer
特征的整数常量,不是定义的操作,编译器不应该编译没有错误?
我尝试用我的常量后缀i32
,但错误信息是相同的,替换_
为i32
.
这里有很多问题:
0
并且1
无法转换为实现的一切Integer
.使用Zero::zero
和One::one
替代.10
绝对不能转换为任何实现Integer
,你需要使用NumCast
它a /= b
不是糖,a = a / b
而是一个Integer
不需要的单独特征.-x
是一个一元的操作,它不属于Integer
但需要Neg
特征(因为它只对签名类型有意义).这是一个实现.请注意,您需要绑定Neg
,以确保它与类型相同T
extern crate num;
use num::{Integer, NumCast};
use std::ops::Neg;
fn int_length<T>(mut x: T) -> u8
where
T: Integer + Neg<Output = T> + NumCast,
{
if x == T::zero() {
return 1;
}
let mut length = 0;
if x < T::zero() {
length += 1;
x = -x;
}
while x > T::zero() {
x = x / NumCast::from(10).unwrap();
length += 1;
}
length
}
fn main() {
println!("{}", int_length(45));
println!("{}", int_length(-45));
}
Run Code Online (Sandbox Code Playgroud)
问题是这个特质可以通过任何东西Integer
来实现。例如,您可以选择在您自己的结构上实现它!没有办法将文字或结构转换为您的结构。我懒得展示实现它的示例,因为有 10 种左右的方法。^_^0
1
num::Zero
和num::One
这就是原因Zero::zero
和One::one
存在。您可以(非常烦人)通过重复调用这些常量来创建所有其他常量。
use num::{One, Zero}; // 0.4.0
fn three<T>() -> T
where
T: Zero + One,
{
let mut three = Zero::zero();
for _ in 0..3 {
three = three + One::one();
}
three
}
Run Code Online (Sandbox Code Playgroud)
From
和Into
您还可以使用From
和Into
特征来转换为您的泛型类型:
use num::Integer; // 0.4.0
use std::ops::{DivAssign, Neg};
fn int_length<T>(mut x: T) -> u8
where
T: Integer + Neg<Output = T> + DivAssign,
u8: Into<T>,
{
let zero = 0.into();
if x == zero {
return 1;
}
let mut length = 0u8;
if x < zero {
length += 1;
x = -x;
}
while x > zero {
x /= 10.into();
length += 1;
}
length
}
fn main() {
println!("{}", int_length(45));
println!("{}", int_length(-45));
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
归档时间: |
|
查看次数: |
1905 次 |
最近记录: |