matrix - 如何将任意大小的矩阵传递给 Rust 中的函数?

标签 matrix types rust

我有一个传递给函数的 3x3 矩阵(一个二维数组):

let matrix: [[i32; 3]; 3] = [
    [0, 0, 0],
    [0, 1, 0],
    [0, 0, 0]
];

filter::convolve(&mut image, matrix, 1).unwrap();

该函数目前硬连线以接受 3x3 矩阵:

pub fn convolve(src: &mut Image, matrix: [[i32; 3]; 3], divisor: i32) -> Result<&mut Image, String> {
    // ...
}

我如何将 3x3、5x5 或任意大小的矩阵传递给同一函数?

最佳答案

数组有固定大小,在编译时确定。 Slices具有固定大小,在运行时确定。

最简单的做法是接受一片切片:

fn convolve(matrix: &[&[i32]]) {
    println!("{:?}", matrix);
}

fn main() {
    let matrix = &[
        &[0, 0, 0][..],
        &[0, 1, 0][..],
        &[0, 0, 0][..],
    ];
    convolve(matrix);
}

这有点烦人,因为您必须使用切片语法 (&foo[..]) 将文字数组转换为切片。您还可以接受泛型,它允许您接受上述内容,但也可以接受任何可以转换为切片的内容:

fn convolve<T, I>(matrix: &[T])
where
    T: AsRef<[I]>,
    I: std::fmt::Debug,
{
    for part in matrix {
        println!("{:?}", part.as_ref());
    }
}

fn main() {
    let matrix = &[
        [0, 0, 0],
        [0, 1, 0],
        [0, 0, 0],
    ];
    convolve(matrix);
}

作为kosinix points out , 不能保证 &[&[i32]] 会有等长的行;可能会有一个参差不齐的数组

对此的运行时解决方案是遍历所有行并确保所有长度都相同。如果您为已验证的矩阵创建新类型,这可以简化为只检查一次:

struct Matrix<'a, T: 'a>(&'a [&'a [T]]);

impl<'a, T> Matrix<'a, T> {
    fn new(slice: &'a [&'a [T]]) -> Result<Self, ()> {
        if slice.is_empty() {
            return Ok(Matrix(slice));
        }

        let (head, tail) = slice.split_at(1);
        let expected = head[0].len();

        if tail.iter().map(|row| row.len()).all(|l| l == expected) {
            Ok(Matrix(slice))
        } else {
            Err(()) // return a real error here
        }
    }
}

现在,只要你有一个 Matrix,你就可以确定所有行的长度都相同。

编译时解决方案……还不存在。这些被称为 const generics . 建议的语法

fn convolve<const N: usize>(matrix: [[i32; N]; N]) 

有可用的稳定解决方法(例如 generic-array ),但这些方法可能以一种或另一种方式受到限制。

关于matrix - 如何将任意大小的矩阵传递给 Rust 中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41051788/

相关文章:

Python 矩阵乘法行与示例代码

c++ - 指向用数组初始化的矩阵的指针数组

java - Scala 的 .type 和 Java 的 .class 字面量

javascript - 有人可以解释一下为什么更具体的输入是不好的吗?

matrix - CSS3 matrix3d矩形到梯形变换

python - 矩阵的自定义回溯功能不起作用

c# - 返回未知的通用列表<T>

rust - 是否可以在 Rust 柴油交易中运行异步函数

rust - "Move"自身的可变引用

rust - 我如何在运行时解释或评估 Rust?