rust - 将大小为 N 的向量转换为超过 32 的固定大小数组长度 N

标签 rust

编辑:这个问题与 Rust >= 1.47 的版本无关因为“常量泛型”已经开始实现。
我正在尝试在 Rust 中实现一个数独求解器以用于学习目的。我正在尝试创建一个具有固定大小 (81) 数组的板 Cell s (即 Copy )但我似乎无法让它工作。我可以创建一行 9 Cell s 所以我想我遇到了只有 TryFrom 的泛型的问题对于这种转换,最多 32 个。Cell现在看起来像这样:

#[derive(Debug, Default, Clone, Copy)]
struct Cell {
    row: u8,
    column: u8,
}
这有效:
use std::convert::TryInto;
fn main() {
    let cells: Vec<Cell> = std::iter::repeat(0)
        .zip(0..9u8)
        .map(|(row, column)| Cell { row, column} )
        .collect();

    let c: Box<[Cell; 9]> = cells.into_boxed_slice().try_into().unwrap();

    println!("{:#?}", c);
}
但这不会:
use std::convert::TryInto;
fn main() {
    let cells: Vec<Cell> = (0..9u8).into_iter()
        .flat_map(|x| {
            std::iter::repeat(x)
                .zip(0..9u8)
        })
        .map(|(row, column)| Cell { row, column} )
        .collect();

    let c: Box<[Cell; 81]> = cells.into_boxed_slice().try_into().unwrap();

    println!("{:#?}", c);
}
我尝试使用来自 std 的代码作为这样的指南:
impl TryFrom<Box<[Cell]>> for Box<[Cell; 81]> {
    type Error = Box<[Cell]>;

    fn try_from(boxed_slice: Box<[Cell]>) -> Result<Self, Self::Error> {
        if boxed_slice.len() == 81 {
            Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [Cell; 91]) })
        } else {
            Err(boxed_slice)
        }
    }
}
但这遇到了关于 conflicting implementations of trait 的错误我想这是有道理的。
我知道我可以使用 Vec或者做类似 [[Cell; 9]; 9] 的事情但我真的很想了解发生了什么。在试图弄清楚这一点时,我看到了许多类似的问题,其中人们试图使用未实现的类型 Copy这就是问题所在,但这里的情况并非如此,我不知道如何进行这项工作。

最佳答案

特质 FromIterator 未为切片实现,您可以将其包装在一个类型中并自己实现:

use core::iter::FromIterator;

#[derive(Debug, Default, Clone, Copy)]
struct Cell {
    row: u8,
    column: u8,
}

#[derive(Debug)]
struct Sudoku(Box<[Cell]>);

impl FromIterator<Cell> for Sudoku {
    fn from_iter<I: IntoIterator<Item=Cell>>(iter: I) -> Self {
        let mut v = Vec::new();
        for cell in iter {
            v.push(cell)
        }
        Sudoku(v.into_boxed_slice())
    }
}

fn main() {
    let cells: Sudoku = (0..9u8).into_iter()
        .flat_map(|x| {
            std::iter::repeat(x)
                .zip(0..9u8)
        })
        .map(|(row, column)| Cell { row, column} )
        .collect();


    println!("{:#?}", cells);
}
Playground
编辑:
您还可以针对数组的特定大小实现它。对于数独案例,这应该没问题,但总的来说,您希望事情以更一般的方式工作。您可以编写一个宏来编写任何给定大小的实现,而不是固定大小。
例子:
use core::iter::FromIterator;
use std::fmt;

#[derive(Clone, Copy)]
struct Cell {
    row: u8,
    column: u8,
}

impl fmt::Display for Cell {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Cell: ({}, {})", self.row, self.column)
    }
}

struct Sudoku([Cell; 81]);

impl fmt::Display for Sudoku {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for cell in self.0.iter() {
            write!(f, "{}\n", cell)?;
        }
        Ok(())
    }
}


impl FromIterator<Cell> for Sudoku {
    fn from_iter<I: IntoIterator<Item=Cell>>(iter: I) -> Self {
        let mut v = [Cell {row: 0, column: 0}; 81];
        for (i, cell) in (0..81).zip(iter) {
            v[i] = cell;
        }
        Sudoku(v)
    }
}

fn main() {
    let cells: Sudoku = (0..9u8).into_iter()
        .flat_map(|x| {
            std::iter::repeat(x)
                .zip(0..9u8)
        })
        .map(|(row, column)| Cell { row, column} )
        .collect();


    println!("{}", cells);
}
Playground

关于rust - 将大小为 N 的向量转换为超过 32 的固定大小数组长度 N,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63864630/

相关文章:

rust - 为什么我要获得 “Cannot Derive Macro In This Scope”?

rust - 向结构添加通用参数后借用检查器错误

rust - 极地使用rust : Read json file like Data Fusion or Spark?

rust - 派生特征会导致意外的编译器错误,但手动实现有效

windows - 如何使 Rust 草书的示例在 Windows 上运行?

rust - 匹配枚举引用并返回 "match arms have incompatible types"中的字符串结果

file - 试图让 Rust 加载文件

rust - 如何从Rust调用原始地址?

Rust String AsRef<T> 不会自动借用 [u8]

rust - 将在 FnMut 上实现的特征传递给辅助函数而不移动