【问题标题】:Type mismatch between type parameter and std::ops::BitXor Output associated type类型参数和 std::ops::BitXor 输出关联类型之间的类型不匹配
【发布时间】:2017-02-28 16:44:09
【问题描述】:

我正在学习 Rust。我发现“过度设计”玩具示例在早期阶段很有用,这导致了我遇到这种情况。

从这个简单的函数开始:

extern crate data_encoding;

use std::ops::BitXor;
use data_encoding::hex;
use std::iter::FromIterator;


fn fixed_xor_basic(l: &[u8], r: &[u8]) -> Vec<u8> {
    l.iter().zip(r.iter()).map(|(x, y)| *x ^ *y).collect()
}

#[test]
fn test_fixed_xor_basic() {
    let input_1 = hex::decode(b"1C0111001F010100061A024B53535009181C").unwrap();
    let input_2 = hex::decode(b"686974207468652062756C6C277320657965").unwrap();

    let expected_output = hex::decode(b"746865206B696420646F6E277420706C6179").unwrap();

    assert_eq!(fixed_xor_basic(&input_1, &input_2), expected_output);
}

我转向一个简单的变体来摆脱分配:

fn fixed_xor_basic_inplace(l: &mut [u8], r: &[u8]) {
    for (left, right) in l.iter_mut().zip(r.iter()) {
        *left = *left ^ *right;
    }
}

另一个接受任何可以异或的类型:

fn fixed_xor_generic<T>(l: &[T], r: &[T]) -> Vec<T>
    where T: BitXor + Copy,
          Vec<T>: FromIterator<<T as BitXor>::Output> {
    l.iter().zip(r.iter()).map(|(x, y)| *x ^ *y).collect()
}

第二个变体最初没有编译——但错误消息提示我要添加约束Vec&lt;T&gt;: FromIterator&lt;&lt;T as BitXor&gt;::Output&gt;。大概这个约束已经给编译器一些暗示BitXor::Output实际上与T是一样的,但我不清楚那个暗示到底是什么。

现在......将两者结合起来让我很难过:

fn fixed_xor_generic_inplace<T>(l: &mut [T], r: &[T])
    where T: BitXor + Copy {
    for (left, right) in l.iter_mut().zip(r.iter()) {
        *left = *left ^ *right;
    }
}

产生错误:

error[E0308]: mismatched types
  --> src/xor_lib.rs:27:17
   |
27 |         *left = *left ^ *right;
   |                 ^^^^^^^^^^^^^^ expected type parameter, found associated type
   |
   = note: expected type `T`
   = note:    found type `<T as std::ops::BitXor>::Output`

error: aborting due to previous error

强烈怀疑这两种情况相似,我需要提供一些额外的上下文来帮助编译器找出T 实际上是&lt;T as std::ops::BitXor&gt;::Output 的另一个名称。

我在正确的轨道上吗?如果有,这个提示是什么?

(下一个挑战是让函数接受 IntoIterator 类型而不是切片——如果这可能会影响解决方案的话)。

【问题讨论】:

    标签: generics syntax rust traits associated-types


    【解决方案1】:

    您只需要告诉编译器关联类型OutputT 相同。

    fn fixed_xor_generic_inplace<T>(l: &mut [T], r: &[T])
        where T: BitXor<Output = T> + Copy {
        for (left, right) in l.iter_mut().zip(r.iter()) {
            *left = *left ^ *right;
        }
    }
    

    【讨论】:

    • 这很简单!这也简化了第一个通用示例 Vec&lt;T&gt;: FromIterator&lt;&lt;T as BitXor&gt;::Output&gt; 不再需要。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 2019-10-19
    • 1970-01-01
    相关资源
    最近更新 更多