类型参数与 std::ops::BitXor 输出关联类型之间的类型不匹配
Type mismatch between type parameter and std::ops::BitXor Output associated type
我正在学习 Rust。我发现 "over-engineering"toy examples 在早期阶段很有用,这让我遇到了这种情况。
从这个简单的函数开始:
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<T>: FromIterator<<T as BitXor>::Output>
。大概这个约束已经给了编译器一些提示,即 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
实际上是<T as std::ops::BitXor>::Output
别名。
我走在正确的轨道上吗?如果是这样,这个提示是什么?
(下一个挑战也是使函数接受 IntoIterator 类型而不是切片——如果这可能会影响解决方案的话)。
你只需要告诉编译器关联类型Output
和T
是一样的。
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;
}
}
我正在学习 Rust。我发现 "over-engineering"toy examples 在早期阶段很有用,这让我遇到了这种情况。
从这个简单的函数开始:
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<T>: FromIterator<<T as BitXor>::Output>
。大概这个约束已经给了编译器一些提示,即 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
实际上是<T as std::ops::BitXor>::Output
别名。
我走在正确的轨道上吗?如果是这样,这个提示是什么?
(下一个挑战也是使函数接受 IntoIterator 类型而不是切片——如果这可能会影响解决方案的话)。
你只需要告诉编译器关联类型Output
和T
是一样的。
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;
}
}