我有这个小片段,但它没有编译,所有错误都源于combinations_n
返回&Vec<&u8>
而不是&Vec<u8>
这一事实。
extern crate itertools;
use std::io;
use std::collections::BTreeMap;
use std::iter::Enumerate;
use itertools::Itertools;
const RANKS: [u8; 13] = [12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
fn is_straight(hand: &Vec<u8>) -> bool {
for (i, h) in hand[1..].iter().enumerate() {
if h - hand[i] != 1 {
return false;
}
}
true
}
fn hand_value(hand: &Vec<u8>) -> u8 {
hand.iter().fold(0_u8, |a, &b| a + 2u8.pow(b as u32));
}
fn generate_flush_table() -> BTreeMap<u8,u8> {
let ft = BTreeMap::new();
let mut straight_counter = 1;
let mut other_counter = 323;
for flush in RANKS.iter().combinations_n(5) {
if flush == [12, 3, 2, 1, 0] {
continue;
} else if is_straight(&flush) {
ft.insert(hand_value(&flush), straight_counter);
straight_counter += 1;
} else {
ft.insert(hand_value(&flush), other_counter);
other_counter += 1;
}
}
ft
}
fn main() {
let flush_table: BTreeMap<u8,u8> = generate_flush_table();
for (key, value) in flush_table.iter() {
println!("{}: {}", key, value);
}
}
以下是编译器所说的内容:
error: the trait bound `&u8: std::cmp::PartialEq<_>` is not satisfied [E0277]
if flush == [12, 3, 2, 1, 0] {
^~~~~~~~~~~~~~~~~~~~~~~~~
help: run `rustc --explain E0277` to see a detailed explanation
help: the following implementations were found:
help: <u8 as std::cmp::PartialEq>
note: required because of the requirements on the impl of `std::cmp::PartialEq<[_; 5]>` for `std::vec::Vec<&u8>`
error: mismatched types [E0308]
} else if is_straight(&flush) {
^~~~~~
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `&std::vec::Vec<u8>`
note: found type `&std::vec::Vec<&u8>`
error: mismatched types [E0308]
ft.insert(hand_value(&flush), straight_counter);
^~~~~~
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `&std::vec::Vec<u8>`
note: found type `&std::vec::Vec<&u8>`
error: mismatched types [E0308]
ft.insert(hand_value(&flush), other_counter);
^~~~~~
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `&std::vec::Vec<u8>`
note: found type `&std::vec::Vec<&u8>`
鉴于flush
返回CombinationsN
并在我阅读的文档中,我真的不明白&Vec<&u8>
的类型如何combinations_n
/ p>
impl<I> Iterator for CombinationsN<I>
where I: Iterator,
I::Item: Clone
{
type Item = Vec<I::Item>
所以它实际上应该是Vec<u8>
。
答案 0 :(得分:4)
作为一名专业程序员,您应该学会制作Minimal, Complete, and Verifiable example。这是一个适合您的问题:
extern crate itertools;
use itertools::Itertools;
const RANKS: [u8; 13] = [12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
fn main() {
let one_combination: () = RANKS.iter().combinations_n(5).next();
}
哪个失败并出现相关错误:
error: mismatched types [E0308]
let one_combination: () = RANKS.iter().combinations_n(5).next();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `()`
note: found type `std::option::Option<std::vec::Vec<&u8>>`
这表明combinations_n
的特定调用确实产生了Vec<&u8>
,而不是Vec<u8>
。
那为什么呢?
CombinationsN
定义中的这一行是关键:
type Item = Vec<I::Item>
CombinationsN
是迭代器适配器,因此I::Item
是它前面的迭代器的类型。在我们的例子中,那是什么?一个slice::Iter
,其中包含:
type Item = &'a T
因此,通过遍历切片,您将获得对切片元素的引用,然后将引用本身传递给CombinationsN
,然后克隆引用并将其收集到Vec
。
一种解决方案是克隆迭代元素:
RANKS.iter().cloned().combinations_n(5)