Rust 如何在没有装箱的情况下从函数中使用'impl Trait'返回对象数组?

Rust 如何在没有装箱的情况下从函数中使用'impl Trait'返回对象数组?,rust,Rust,我正在实现一个数独游戏箱,我想让更高维度的数独游戏成为可能。在2维中,有3组需要检查其正确性(基本规则仅包含3个子规则),位置(根据定义)只需要2个坐标即可完全指定,但在更高维中,这显然会增加 我编写了下面的方法签名,但它不起作用,而且由于我正在开发的环境,我希望不惜一切代价避免装箱 pub fn groups(position: [u8; DIMENSIONS]) -> [impl Group; DIMENSIONS + 1] 每个组的实际类型将在编译时已知(实际类型类似于[Box,S

我正在实现一个数独游戏箱,我想让更高维度的数独游戏成为可能。在2维中,有3组需要检查其正确性(基本规则仅包含3个子规则),位置(根据定义)只需要2个坐标即可完全指定,但在更高维中,这显然会增加

我编写了下面的方法签名,但它不起作用,而且由于我正在开发的环境,我希望不惜一切代价避免装箱

pub fn groups(position: [u8; DIMENSIONS]) -> [impl Group; DIMENSIONS + 1]
每个组的实际类型将在编译时已知(实际类型类似于
[Box,Stack,Band]
),但编译器似乎不喜欢这样,即使它知道每个元素的大小

我希望能够使用在编译时确定大小的元组,但这似乎不容易被支持,除非我遗漏了什么


其思想是:有一个
堆栈
(列)、一个
(行)和一个
。下面给出了
的定义

pub trait Group {
    /// A group is considered valid if it has contains only unique elements.
    fn is_valid(&self) -> bool { /* Default implementation elided. */ }
    /// Returns an owned copy of the group's constituent elements.
    fn elements(&self) -> Vec<Option<Element>>;
}
pub特征组{
///如果组仅包含唯一元素,则认为该组有效。
fn是有效的(&self)->bool{/*默认实现被省略。*/}
///返回组的组成元素的所有者副本。
fn元素(自身)->Vec;
}
让我们从二维的例子开始。对于给定的元素,我们可以将元素的索引编写为双元组(即2元组)
(x,y)
。与此元素关联的组是一个
(一如既往;这是
维度+1
的来源)、一个
堆栈
、一个

在三维中,给定元素(根据定义)由三元组(即3元组)
(x,y,z)
索引。与此元素关联的组是一个
、一个
堆栈
、两个
s

这种趋势将继续发展到更高的维度,我希望使用户能够使用不同的维度,从而在编译时确定大小


为了检查拼图的正确性,调用方只需对每个
puzzle.groups()
调用
Group::is\u valid()
;他们还可以根据需要对每个属性进行迭代以呈现谜题。

您不能这样做,因为所有
impl Trait
都保证它是实现
Trait
的某种类型。Rust中的数组是同质的,每个元素必须是相同的类型,但是类似于
[impl Group;DIMENSIONS+1]
的东西意味着每个元素可以是任何类型,只要它实现
Group

很难说没有更多的代码,但这可以通过参数化
组的类型来实现:

pub fn groups<T: Group>(position: [u8; DIMENSIONS]) -> [T; DIMENSIONS + 1]

这正是我所担心的——我怀疑没有办法制作一个异构数组,但我希望有办法。有没有另一种方法来表示“我将给你一个完全由n个值组成的有序集合,所有这些值都实现了这个特性?”我也不反对使用程序宏生成n元组之类的东西,如果我必须这样做的话。可能有一些事情可以做,我很乐意提供帮助,但我真的很难想象你到底想做什么。请您再添加一些上下文,例如一些类型和函数调用不同方式的示例,好吗?它不需要编译,尽管这也会有帮助。否则,作为一种猜测,一种传统的方法可以做到这一点,但我同样缺乏上下文,所以在您的情况下,这可能会被关闭,就是创建一个枚举,这样您就有了
枚举组{Box,Stack,Band}
,因为每个变量仍然是相同的类型,您可以将每一个存储在同一个数组中:
[Group::Box,Group::Stack,Group::Band]
。如果需要,可以使用枚举结构变量直接在变量中添加其他数据,例如
枚举组{Box{size:u8,name:String},…}
如果不想以结构变量的形式直接在变量中存储数据,还可以创建嵌入到变量中的单独结构,例如,
struct-Box{…}
enum-Group{Box(Box),…}
。它本质上是相同的,但具有不同的人体工程学,在这种情况下,您可以轻松地将包含的
从enum变体中取出后传递给其他对象。问得好,不是。将枚举视为标记的C并集,因此每个变量占用相同的大小(或多或少是任何变量的最大大小,给定或获取填充/对齐)。根据您的情况,您可能可以通过存储对结构的引用而不是数据本身来最小化这一点。此外,如果出于任何原因仍然需要trait,您仍然可以将它作为一个整体用于enum,只是数组现在包含enum类型。
pub fn groups<T: Group, const DIMENSIONS: usize>(position: [u8; DIMENSIONS])
  -> [T; DIMENSIONS + 1]