【问题标题】:Returning an multidimensional array of unknown size from a function in Rust从 Rust 中的函数返回一个未知大小的多维数组
【发布时间】:2019-06-11 04:34:33
【问题描述】:

我有一个 trait,MyTrait,它定义了一个名为 my_func 的方法,它返回一个未知大小的数组。这样做的原因是从这个方法返回的数组的大小将取决于实现 trait 的结构。因此,方法定义如下所示:

MyTrait<T: Clone + Float> {
    fn my_func() -> &[&[T]];
}

现在,我正在尝试使用以下方法实现此 trait:

impl MyStruct {
    const matrix_desc: [[u32; 4]; 4] = [
        [1, 0, 0, 0],
        [0, 1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1]
    ];
}

impl MyTrait<u32> for MyStruct {
    fn my_func() -> &[&[u32]] {
        &matrix_desc
    }
}

但是,我不断收到错误消息,说存在类型不匹配,Rust 期望 &amp;[&amp;[u32]] 但得到 &amp;[[u32; 4]; 4]。这对我来说很清楚,但我不知道如何解决它。我也尝试过使用 Sized 特征,但我似乎无法让它发挥作用。有谁知道我如何在编译时返回未知大小的数组?

另外,对于奖励积分,有谁知道我可以如何强制这个二维数组为正方形?

【问题讨论】:

  • 这似乎是Vec 会有所帮助的情况。你有什么理由不能返回 Vec&lt;Vec&lt;T&gt;&gt; 吗?
  • @Sunreef,是什么让向量变得如此出色以至于值得 4x4 矩阵?
  • @JanHudec 如果它总是一个 4x4 矩阵,那么你可以使用[[T;4];4]。但他说他想要未知尺寸。这就是Vec 所做的。
  • @Sunreef,你可以用简单的参考做未知尺寸。 Vec 添加的东西是所有权。如果不需要,则不应存在。
  • @Sunreef 实现特征时矩阵的实际大小不会改变,我只是不知道特征定义的大小。例如,我可以有一个名为StructB 的第二个结构,它实现了[[T;8];8]。我不希望矩阵大小在实现时发生变化,但我无法确定特征定义中的大小

标签: arrays rust


【解决方案1】:

已知长度数组是直接包含在包含对象中的值。所以[[u32; 4]; 4] 是一个有 16 个u32s 的内存块。您可以将其转换为 &amp;[[u32;4]],它是一个指针和行数,但 &amp;[&amp;[u32]] 想要指向一个指针大小对的数组,并且在原始值中不存在。

就像在 C 中一样,嵌套数组并不是特别好用。我可能会将其扁平化为[u32; 4 * 4]&amp;[u32],并可能用定义std::ops::Index&lt;(usize, usize)&gt; 的东西包装它。这会立即强制矩阵为矩形(&amp;[&amp;[u32]] 可以有不同长度的每一行),您可以进一步检查它在 index 方法(以及您为代数定义的任何其他方法)中实际上是方形的。

或者只是尝试在 crates.io 上找到一个已经编写好的矩阵库——我很确定会有一些。

【讨论】:

  • 对于像 4x4、3x3 和小向量这样的小矩阵,nalgebra 是一个非常好的 crate。
【解决方案2】:

如果可以将matrix_desc 声明为切片,则应该可以:

struct MyStruct;

impl MyStruct {
    const matrix_desc: &'static [&'static [u32]] = &[
        &[1, 0, 0, 0],
        &[0, 1, 0, 0],
        &[0, 0, 1, 0],
        &[0, 0, 0, 1]
    ];
}

trait MyTrait<T> {
    fn my_func() -> &'static [&'static [T]];
}

impl MyTrait<u32> for MyStruct {
    fn my_func() -> &'static [&'static [u32]] {
        &Self::matrix_desc
    }
}

目前看来,固定和通用大小的数组并没有得到很好的支持。例如,这不起作用:

trait MyTrait<T> {
    const SIZE: usize;
    fn my_func() -> [[T; SIZE]; SIZE];
}

【讨论】:

  • 我也试过了,这可能是我最终要走的路线
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 2017-03-06
  • 2018-01-05
  • 2011-03-01
相关资源
最近更新 更多