在为多层嵌套数组实现 From 时,如何避免指定常量泛型值?

发布于 2025-01-13 01:52:05 字数 1652 浏览 3 评论 0原文

我正在尝试创建一个具有一些友好的 From 特征实现的结构。该结构是数组数组的数组的包装器,用于表示 3D 矩阵。

pub struct Table<T, const X: usize, const Y: usize, const Z: usize> {
    pub content: [[[T; X]; Y]; Z],
}

impl<T, const X: usize> From<[T; X]> for Table<T, X, 1, 1> {
    fn from(row: [T; X]) -> Self {
        Table { content: [[row]] }
    }
}

impl<T, const X: usize, const Y: usize> From<[[T; X]; Y]> for Table<T, X, Y, 1> {
    fn from(layer: [[T; X]; Y]) -> Self {
        Table { content: [layer] }
    }
}

impl<T, const X: usize, const Y: usize, const Z: usize> From<[[[T; X]; Y]; Z]>
    for Table<T, X, Y, Z>
{
    fn from(matrix: [[[T; X]; Y]; Z]) -> Self {
        Table { content: matrix }
    }
}

fn main() {
    let i1 = [1];
    let i2 = [[1]];
    let i3 = [[[1]]];

    // Table<i32>
    // notice how you can avoid specifying the constant values
    let tbl1 = Table::from(i1);

    // type annotations needed
    // cannot infer type for struct `Table<_, {_: usize}, {_: usize}, {_: usize}>`
    // let tbl2 = Table::from(i2);
}

我尝试了一些替代解决方案,包括:

  1. to_table 特征解决方案(这反过来会导致相同的问题)
  2. Macro_rules (无法确定提供的类型是否嵌套在数组中。我的宏经验很少)
  3. 特定类型 impl(s) (这可行,但这是一个糟糕的选择,因为它限制了我可以用来填充表的开箱即用支持类型的数量)

我很想了解如何区分泛型类型实现和内的泛型类型实现数组。我觉得我的根本问题是 T[T; _] 是同一件事 - 或者更确切地说,它们使编译器感到困惑。

替代问题:有没有办法在 Rust 中指定元素的非常量泛型类型?如果使用有效,我会很高兴

// possible to skip X, Y, Z?
let tbl: Table<i32> = Table::from([[1]]);

,但是如果您手动输入通用属性,则必须指定所有常量的长度。对第二点的澄清也将不胜感激。

I am attempting to create a structure with a few friendly From trait implementations. The structure is a wrapper for an array of arrays of arrays to represent a 3D matrix.

pub struct Table<T, const X: usize, const Y: usize, const Z: usize> {
    pub content: [[[T; X]; Y]; Z],
}

impl<T, const X: usize> From<[T; X]> for Table<T, X, 1, 1> {
    fn from(row: [T; X]) -> Self {
        Table { content: [[row]] }
    }
}

impl<T, const X: usize, const Y: usize> From<[[T; X]; Y]> for Table<T, X, Y, 1> {
    fn from(layer: [[T; X]; Y]) -> Self {
        Table { content: [layer] }
    }
}

impl<T, const X: usize, const Y: usize, const Z: usize> From<[[[T; X]; Y]; Z]>
    for Table<T, X, Y, Z>
{
    fn from(matrix: [[[T; X]; Y]; Z]) -> Self {
        Table { content: matrix }
    }
}

fn main() {
    let i1 = [1];
    let i2 = [[1]];
    let i3 = [[[1]]];

    // Table<i32>
    // notice how you can avoid specifying the constant values
    let tbl1 = Table::from(i1);

    // type annotations needed
    // cannot infer type for struct `Table<_, {_: usize}, {_: usize}, {_: usize}>`
    // let tbl2 = Table::from(i2);
}

I have tried a few alternative solutions including:

  1. to_table trait solution (which lead to the same issue in reverse)
  2. macro_rules (was unable to determine whether the provided types were nested within arrays. I have minimal macro experience)
  3. specific type impl(s) (this works, but is a bad choice because it limits the number of out-of-the-box supported types I could use to populate a table)

I would love to understand how to distinguish generic type implementations from generic type implementations within arrays. I feel that my fundamental issue is that
T and [T; _] are the same thing- or rather they confuse the compiler.

Alternative question: Is there a way to specify the non-constant generic types of an element in Rust? I would be happy if using

// possible to skip X, Y, Z?
let tbl: Table<i32> = Table::from([[1]]);

worked, but you have to go through specifying the lengths of all the constants if you manually enter the generic property. Clarification on this second point would be greatly appreciated as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文