在用 C# 或 C++ 编写严重依赖泛型/模板的库时,我经常使用的一个技巧是声明几个使用与静态类下的嵌套类型相同的泛型类型参数的结构。
例如这些声明(以 C# 为例):
public struct Gen1<T1, T2, T3>
{
}
public struct Gen2<T1, T2, T3>
{
}
在功能上等同于:
public static class Ts<T1, T2, T3>
{
public struct Gen1
{
}
public struct Gen2
{
}
}
即,Ts
我在大多数其他语言中都没有找到类似的抽象(唯一的例外是 LEAN4,其中静态泛型类成为一个部分:https://lean-lang.org/lean4/doc/sections.html)。当将此类代码转换为 Rust 时,大多数法学硕士会建议使用 mod 功能(没有通用/模板)并给出明显有缺陷的答案,例如以下来自 Claude 3.5 的答案:
mod container<T> {
pub struct Holder {
value: T,
}
impl<T> Holder {
pub fn new(value: T) -> Self {
Holder { value }
}
pub fn get(&self) -> &T {
&self.value
}
}
}
转换此类声明的最简单/最短的方法是什么?
Rust 不支持在结构内定义结构(是的
mod
不能引入泛型)。所以 Rust 的等价物看起来就像第一个 C# 片段; Gen1
和 Gen2
需要用它们自己的通用参数单独定义。
如果您希望
Ts
与 Gen1
和 Gen2
具有强关联,您可以使用关联类型声明来实现,但只能通过特征实现(直到支持固有关联特征) )。 Rust 中的情况如下:
struct TsGen1<T1, T2, T3> {
// ... fields
}
struct TsGen2<T1, T2, T3> {
// ... fields
}
struct Ts<T1, T2, T3> {
// ... fields
}
trait Gen {
type Gen1;
type Gen2;
}
impl<T1, T2, T3> Gen for Ts<T1, T2, T3> {
type Gen1 = TsGen1<T1, T2, T3>;
type Gen2 = TsGen2<T1, T2, T3>;
}
然后您可以将“嵌套”类型称为 Ts<A, B, C>::Gen1
。如果您想要这样的组织,那么很有帮助,但如果您只是想简化定义,则没有帮助。