Types 为什么可以';t trust推断迭代器::sum的结果类型?
此代码适用于:Types 为什么可以';t trust推断迭代器::sum的结果类型?,types,rust,type-inference,Types,Rust,Type Inference,此代码适用于: fn main() { let a: i32 = (1i32..10).sum(); let b = a.pow(2); } 如果从a中删除i32类型,则会出现以下错误: rustc 1.13.0(2c6933acc 2016-11-07) 错误:此值的类型在此上下文中必须是已知的 --> 我本以为锈蚀会将(1i32..10)变成i32迭代器,然后sum()知道返回i32。我错过了什么 然后sum()知道返回一个i32 这是关键缺失点。虽然“输入”类型已经是已知
fn main() {
let a: i32 = (1i32..10).sum();
let b = a.pow(2);
}
如果从a
中删除i32
类型,则会出现以下错误:
rustc 1.13.0(2c6933acc 2016-11-07)
错误:此值的类型在此上下文中必须是已知的
-->
我本以为锈蚀会将(1i32..10)
变成i32
迭代器,然后sum()
知道返回i32
。我错过了什么
然后sum()
知道返回一个i32
这是关键缺失点。虽然“输入”类型已经是已知的(它必须是实现迭代器
的东西,以便求和
可用),但“输出”类型非常灵活
退房:
没错!您可以将u8的迭代器
或&u8的迭代器
相加!如果我们没有这个,那么这个代码就不起作用了:
fn main() {
let a: i32 = (0..5).sum();
let b: i32 = [0, 1, 2, 3, 4].iter().sum();
assert_eq!(a, b);
}
,我们可以通过一个关联的类型来实现这一点,该类型将绑定u8->u8
和&'aU8->u8
但是,如果我们只有一个关联的类型,那么目标和类型将始终是固定的,我们将失去灵活性。有关更多详细信息,请参阅
例如,我们还可以为自己的类型实现Sum
。在这里,我们对u8
s进行求和,但要增加求和类型的大小,因为求和很可能会超过au8
。此实现是对标准库中现有实现的补充:
impl Sum<i8> for i8
impl<'a> Sum<&'a i8> for i8
#[derive(Debug, Copy, Clone)]
struct Points(i32);
impl std::iter::Sum<u8> for Points {
fn sum<I>(iter: I) -> Points
where
I: Iterator<Item = u8>,
{
let mut pts = Points(0);
for v in iter {
pts.0 += v as i32;
}
pts
}
}
fn main() {
let total: Points = (0u8..42u8).sum();
println!("{:?}", total);
}
#[派生(调试、复制、克隆)]
结构点(i32);
impl std::iter::积分总和{
fn总和(国际热核实验堆:I)->点数
哪里
I:迭代器,
{
设mut pts=点(0);
iter中的v{
pts.0+=v为i32;
}
临时秘书处
}
}
fn main(){
总数:点数=(0u8..42u8).sum();
println!(“{:?}”,总计);
}
然后sum()
知道返回一个i32
这是关键缺失点。虽然“输入”类型已经是已知的(它必须是实现迭代器
的东西,以便求和
可用),但“输出”类型非常灵活
退房:
没错!您可以将u8的迭代器
或&u8的迭代器
相加!如果我们没有这个,那么这个代码就不起作用了:
fn main() {
let a: i32 = (0..5).sum();
let b: i32 = [0, 1, 2, 3, 4].iter().sum();
assert_eq!(a, b);
}
,我们可以通过一个关联的类型来实现这一点,该类型将绑定u8->u8
和&'aU8->u8
但是,如果我们只有一个关联的类型,那么目标和类型将始终是固定的,我们将失去灵活性。有关更多详细信息,请参阅
例如,我们还可以为自己的类型实现Sum
。在这里,我们对u8
s进行求和,但要增加求和类型的大小,因为求和很可能会超过au8
。此实现是对标准库中现有实现的补充:
impl Sum<i8> for i8
impl<'a> Sum<&'a i8> for i8
#[derive(Debug, Copy, Clone)]
struct Points(i32);
impl std::iter::Sum<u8> for Points {
fn sum<I>(iter: I) -> Points
where
I: Iterator<Item = u8>,
{
let mut pts = Points(0);
for v in iter {
pts.0 += v as i32;
}
pts
}
}
fn main() {
let total: Points = (0u8..42u8).sum();
println!("{:?}", total);
}
#[派生(调试、复制、克隆)]
结构点(i32);
impl std::iter::积分总和{
fn总和(国际热核实验堆:I)->点数
哪里
I:迭代器,
{
设mut pts=点(0);
iter中的v{
pts.0+=v为i32;
}
临时秘书处
}
}
fn main(){
总数:点数=(0u8..42u8).sum();
println!(“{:?}”,总计);
}
定义sum
的方式,返回值是开放的;不止一种类型可以实现traitSum
。下面是一个示例,其中使用了a
的不同类型,这两种类型都可以编译:
#[derive(Clone, Copy)]
struct Summer {
s: isize,
}
impl Summer {
fn pow(&self, p: isize) {
println!("pow({})", p);
}
}
impl std::iter::Sum<i32> for Summer {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = i32>,
{
let mut result = 0isize;
for v in iter {
result += v as isize;
}
Summer { s: result }
}
}
fn main() {
let a1: i32 = (1i32..10).sum();
let a2: Summer = (1i32..10).sum();
let b1 = a1.pow(2);
let b2 = a2.pow(2);
}
#[派生(克隆,复制)]
结构夏季{
s:isize,
}
夏天{
fn pow(&self,p:isize){
println!(“pow({})”,p);
}
}
impl std::iter::夏季总和{
fn sum(iter:I)->自
哪里
I:迭代器,
{
让mut result=0isize;
iter中的v{
结果+=v为isize;
}
夏季{s:result}
}
}
fn main(){
设a1:i32=(1i32..10).sum();
设a2:Summer=(1i32..10).sum();
设b1=a1.pow(2);
设b2=a2.pow(2);
}
由于两种结果类型都是可能的,因此无法推断该类型,必须通过turbofish(sum::()
)或表达式的结果(let x:x=…sum();
)显式指定该类型。定义sum
的方式,返回值是开放的;不止一种类型可以实现traitSum
。下面是一个示例,其中使用了a
的不同类型,这两种类型都可以编译:
#[derive(Clone, Copy)]
struct Summer {
s: isize,
}
impl Summer {
fn pow(&self, p: isize) {
println!("pow({})", p);
}
}
impl std::iter::Sum<i32> for Summer {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = i32>,
{
let mut result = 0isize;
for v in iter {
result += v as isize;
}
Summer { s: result }
}
}
fn main() {
let a1: i32 = (1i32..10).sum();
let a2: Summer = (1i32..10).sum();
let b1 = a1.pow(2);
let b2 = a2.pow(2);
}
#[派生(克隆,复制)]
结构夏季{
s:isize,
}
夏天{
fn pow(&self,p:isize){
println!(“pow({})”,p);
}
}
impl std::iter::夏季总和{
fn sum(iter:I)->自
哪里
I:迭代器,
{
让mut result=0isize;
iter中的v{
结果+=v为isize;
}
夏季{s:result}
}
}
fn main(){
设a1:i32=(1i32..10).sum();
设a2:Summer=(1i32..10).sum();
设b1=a1.pow(2);
设b2=a2.pow(2);
}
由于这两种结果类型都是可能的,因此无法推断该类型,必须通过turbofish(sum::()
)或表达式的结果(let x:x=…sum();
)显式指定该类型;仅仅因为多个类型想要求和到同一事物,并不意味着必须有另一个类型参数。它可以通过关联类型&'a i8->i8
和i8->i8
来解决。谢谢。我的意思是,这不是你的问题,它在图书馆里,但由于这个答案是通过一些步骤来合理化它,我想指出它。无论如何,合理化现有的impl可能是通往幸福的道路;-)我认为这是一个逻辑步骤缺失;仅仅因为多个类型想要求和到同一个东西,并不意味着一定要有