接受任何可索引数据类型作为参数的函数
Function that accepts any indexable data type as an argument
我正在尝试创建一个函数,该函数可以采用任何接受 []
运算符的 class。我希望它能够接受:
按引用或按值排列数组
向量或任何其他可以索引的容器
通过一些实验,我发现我还需要一些其他特征,例如 PartialOrd
、PartialEq
。我还需要找出容器中有多少对象。
这是我的代码:
use std::ops::Index;
use std::iter::ExactSizeIterator;
use std::cmp::PartialEq;
pub fn find<'a, I>(input: I, key: <I as std::ops::Index<u32>>::Output) -> Option<u32>
where
I: Index<u32> + ExactSizeIterator,
<I as std::ops::Index<u32>>::Output: PartialEq + std::marker::Sized + std::cmp::PartialOrd,
{
if input.len() == 0 {
return None;
}
if key < input[0] || key > input[(input.len() - 1) as u32] {
return None;
}
let mut index: u32 = (input.len() - 1) as u32;
loop {
if key < input[index] {
index /= 2;
continue;
} else if input[index] < key && input[index + 1] > key {
return None;
} else if key > input[index] {
index += index / 2;
continue;
} else if input[index] == key {
return Some(index);
} else {
return None;
}
}
}
fn main() {
assert_eq!(find(&[1, 2], 2), Some(1));
assert_eq!(find([1, 2], 2), Some(1));
assert_eq!(find(vec![1, 2], 2), Some(1));
}
它产生这些错误:
error[E0277]: the trait bound `&[{integer}; 2]: std::ops::Index<u32>` is not satisfied
--> src/main.rs:36:16
|
36 | assert_eq!(find(&[1, 2], 2), Some(1));
| ^^^^ the type `&[{integer}; 2]` cannot be indexed by `u32`
|
= help: the trait `std::ops::Index<u32>` is not implemented for `&[{integer}; 2]`
= note: required by `find`
error[E0277]: the trait bound `&[{integer}; 2]: std::iter::ExactSizeIterator` is not satisfied
--> src/main.rs:36:16
|
36 | assert_eq!(find(&[1, 2], 2), Some(1));
| ^^^^ the trait `std::iter::ExactSizeIterator` is not implemented for `&[{integer}; 2]`
|
= note: required by `find`
error[E0277]: the trait bound `[{integer}; 2]: std::ops::Index<u32>` is not satisfied
--> src/main.rs:37:16
|
37 | assert_eq!(find([1, 2], 2), Some(1));
| ^^^^ the type `[{integer}; 2]` cannot be indexed by `u32`
|
= help: the trait `std::ops::Index<u32>` is not implemented for `[{integer}; 2]`
= note: required by `find`
error[E0277]: the trait bound `[{integer}; 2]: std::iter::ExactSizeIterator` is not satisfied
--> src/main.rs:37:16
|
37 | assert_eq!(find([1, 2], 2), Some(1));
| ^^^^ the trait `std::iter::ExactSizeIterator` is not implemented for `[{integer}; 2]`
|
= note: required by `find`
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index<u32>` is not satisfied
--> src/main.rs:38:16
|
38 | assert_eq!(find(vec![1, 2], 2), Some(1));
| ^^^^ the type `std::vec::Vec<{integer}>` cannot be indexed by `u32`
|
= help: the trait `std::ops::Index<u32>` is not implemented for `std::vec::Vec<{integer}>`
= note: required by `find`
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::iter::ExactSizeIterator` is not satisfied
--> src/main.rs:38:16
|
38 | assert_eq!(find(vec![1, 2], 2), Some(1));
| ^^^^ the trait `std::iter::ExactSizeIterator` is not implemented for `std::vec::Vec<{integer}>`
|
= note: required by `find`
我找到了实现它的方法,但有一些限制。
pub struct Validator {
data: Vec<i32>,
}
impl<'a> From<&'a [i32; 2]> for Validator {
fn from(input: &'a [i32; 2]) -> Self {
Validator {
data: input.iter().map(|c| *c).collect(),
}
}
}
impl From<[i32; 2]> for Validator {
fn from(input: [i32; 2]) -> Self {
Validator {
data: input.iter().map(|c| *c).collect(),
}
}
}
impl From<Vec<i32>> for Validator {
fn from(input: Vec<i32>) -> Self {
Validator { data: input }
}
}
pub fn find<T>(input: T, key: i32) -> Option<usize>
where
T: std::convert::Into<Validator>,
Validator: std::convert::From<T>,
{
let input: Vec<i32> = input.into().data;
if input.len() == 0 {
return None;
}
if key < input[0] || key > input[(input.len() - 1)] {
return None;
}
let mut index = input.len() - 1;
loop {
if key < input[index] {
index /= 2;
continue;
} else if input[index] < key && input[index + 1] > key {
return None;
} else if key > input[index] {
index += index / 2;
continue;
} else if input[index] == key {
return Some(index);
} else {
return None;
}
}
}
fn main() {
assert_eq!(find(&[1, 2], 2), Some(1));
assert_eq!(find([1, 2], 2), Some(1));
assert_eq!(find(vec![1, 2], 2), Some(1));
}
如果您需要一个接受 3 个或更多数字的数组的函数,则必须为每个元素数量实现它。您可以通过为验证器结构和您想要支持的类型实现 Into
特性来添加对更多结构的支持,例如 VecDeque
或自定义结构。
我正在尝试创建一个函数,该函数可以采用任何接受 []
运算符的 class。我希望它能够接受:
按引用或按值排列数组
向量或任何其他可以索引的容器
通过一些实验,我发现我还需要一些其他特征,例如 PartialOrd
、PartialEq
。我还需要找出容器中有多少对象。
这是我的代码:
use std::ops::Index;
use std::iter::ExactSizeIterator;
use std::cmp::PartialEq;
pub fn find<'a, I>(input: I, key: <I as std::ops::Index<u32>>::Output) -> Option<u32>
where
I: Index<u32> + ExactSizeIterator,
<I as std::ops::Index<u32>>::Output: PartialEq + std::marker::Sized + std::cmp::PartialOrd,
{
if input.len() == 0 {
return None;
}
if key < input[0] || key > input[(input.len() - 1) as u32] {
return None;
}
let mut index: u32 = (input.len() - 1) as u32;
loop {
if key < input[index] {
index /= 2;
continue;
} else if input[index] < key && input[index + 1] > key {
return None;
} else if key > input[index] {
index += index / 2;
continue;
} else if input[index] == key {
return Some(index);
} else {
return None;
}
}
}
fn main() {
assert_eq!(find(&[1, 2], 2), Some(1));
assert_eq!(find([1, 2], 2), Some(1));
assert_eq!(find(vec![1, 2], 2), Some(1));
}
它产生这些错误:
error[E0277]: the trait bound `&[{integer}; 2]: std::ops::Index<u32>` is not satisfied
--> src/main.rs:36:16
|
36 | assert_eq!(find(&[1, 2], 2), Some(1));
| ^^^^ the type `&[{integer}; 2]` cannot be indexed by `u32`
|
= help: the trait `std::ops::Index<u32>` is not implemented for `&[{integer}; 2]`
= note: required by `find`
error[E0277]: the trait bound `&[{integer}; 2]: std::iter::ExactSizeIterator` is not satisfied
--> src/main.rs:36:16
|
36 | assert_eq!(find(&[1, 2], 2), Some(1));
| ^^^^ the trait `std::iter::ExactSizeIterator` is not implemented for `&[{integer}; 2]`
|
= note: required by `find`
error[E0277]: the trait bound `[{integer}; 2]: std::ops::Index<u32>` is not satisfied
--> src/main.rs:37:16
|
37 | assert_eq!(find([1, 2], 2), Some(1));
| ^^^^ the type `[{integer}; 2]` cannot be indexed by `u32`
|
= help: the trait `std::ops::Index<u32>` is not implemented for `[{integer}; 2]`
= note: required by `find`
error[E0277]: the trait bound `[{integer}; 2]: std::iter::ExactSizeIterator` is not satisfied
--> src/main.rs:37:16
|
37 | assert_eq!(find([1, 2], 2), Some(1));
| ^^^^ the trait `std::iter::ExactSizeIterator` is not implemented for `[{integer}; 2]`
|
= note: required by `find`
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index<u32>` is not satisfied
--> src/main.rs:38:16
|
38 | assert_eq!(find(vec![1, 2], 2), Some(1));
| ^^^^ the type `std::vec::Vec<{integer}>` cannot be indexed by `u32`
|
= help: the trait `std::ops::Index<u32>` is not implemented for `std::vec::Vec<{integer}>`
= note: required by `find`
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::iter::ExactSizeIterator` is not satisfied
--> src/main.rs:38:16
|
38 | assert_eq!(find(vec![1, 2], 2), Some(1));
| ^^^^ the trait `std::iter::ExactSizeIterator` is not implemented for `std::vec::Vec<{integer}>`
|
= note: required by `find`
我找到了实现它的方法,但有一些限制。
pub struct Validator {
data: Vec<i32>,
}
impl<'a> From<&'a [i32; 2]> for Validator {
fn from(input: &'a [i32; 2]) -> Self {
Validator {
data: input.iter().map(|c| *c).collect(),
}
}
}
impl From<[i32; 2]> for Validator {
fn from(input: [i32; 2]) -> Self {
Validator {
data: input.iter().map(|c| *c).collect(),
}
}
}
impl From<Vec<i32>> for Validator {
fn from(input: Vec<i32>) -> Self {
Validator { data: input }
}
}
pub fn find<T>(input: T, key: i32) -> Option<usize>
where
T: std::convert::Into<Validator>,
Validator: std::convert::From<T>,
{
let input: Vec<i32> = input.into().data;
if input.len() == 0 {
return None;
}
if key < input[0] || key > input[(input.len() - 1)] {
return None;
}
let mut index = input.len() - 1;
loop {
if key < input[index] {
index /= 2;
continue;
} else if input[index] < key && input[index + 1] > key {
return None;
} else if key > input[index] {
index += index / 2;
continue;
} else if input[index] == key {
return Some(index);
} else {
return None;
}
}
}
fn main() {
assert_eq!(find(&[1, 2], 2), Some(1));
assert_eq!(find([1, 2], 2), Some(1));
assert_eq!(find(vec![1, 2], 2), Some(1));
}
如果您需要一个接受 3 个或更多数字的数组的函数,则必须为每个元素数量实现它。您可以通过为验证器结构和您想要支持的类型实现 Into
特性来添加对更多结构的支持,例如 VecDeque
或自定义结构。