Generics 不带类型参数的泛型类型上的泛型结构

Generics 不带类型参数的泛型类型上的泛型结构,generics,rust,higher-kinded-types,Generics,Rust,Higher Kinded Types,有可能在生锈的地方做这样的事情吗 trait Foo<T> {} struct A; struct B; struct Bar<T: Foo> { a: T<A>, b: T<B> } trait Foo{} 结构A; 结构B; 结构条{ a:T, b:T } 我知道我可以使用两个参数来设置Bar,但我认为必须有更好的方法来实现这一点 我想实现一个图结构。因为我不能只将节点和边绑定到它们的父生命周期,所以我想要类似于Rc的东

有可能在生锈的地方做这样的事情吗

trait Foo<T> {}

struct A;
struct B;

struct Bar<T: Foo> {
    a: T<A>,
    b: T<B>
}
trait Foo{}
结构A;
结构B;
结构条{
a:T,
b:T
}
我知道我可以使用两个参数来设置
Bar
,但我认为必须有更好的方法来实现这一点

我想实现一个
结构。因为我不能只将节点和边绑定到它们的父生命周期,所以我想要类似于
Rc
的东西。但是,有时可能需要一个具有多线程访问权限的
图。因此,我必须同时使用
Rc
Arc
实现


这就是
Foo
的好处:我为
Rc
Arc
实现
Foo
Foo
需要
Deref
),并使用绑定到
Foo
的参数
T
。这就是我希望单线程和多线程使用一个结构的原因。

⇒ 这是目前无法在Rust的类型系统中表达的

幸运的是,由于中提出的“泛型关联类型”,这将在将来成为可能。您可以跟踪中的实施和稳定状态


这里的重要术语是“HKT”(higherkindedtypes)。这是尚未在Rust中实现的类型系统的一个特性。Haskell提供HKTs。在C++世界中,HTTS被称为“模板模板”。上述泛型关联类型也是HKTs的一种形式

但什么是HKT,真的? 让我们慢慢开始:我们所知道的简单类型是什么?让我们列出一些类型:
i32
bool
String
。这些都是类型。。。您可以有这些类型的值(变量)。那Vec呢?这也是一个简单的类型!您可以使用
Vec
类型的变量,没问题

我们想把这些类型组合在一起;我们称这种分类为“一种类型”。如果我们想以一种非常抽象的方式谈论(关于类型的类型),我们可以选择其他的词,在本例中是kind。甚至还有各种类型的符号。对于上面的简单类型,我们说:这些类型的类型是

*
是的,只是一颗星星,很简单。这个符号以后会更有意义


让我们搜索与简单类型不同的类型<代码>互斥体
?不,它可能相当复杂,但它仍然是一种
*
,我们仍然可以有这种类型的变量

那Vec呢?是的,我们省略了尖括号。是的,这确实是另一种类型!我们可以有一个
Vec
类型的变量吗?不什么向量

这类捐款的形式如下:

* -> *
这只是说:给我一个普通类型(
*
),我会返回一个普通类型!给这个东西(
Vec
)一个普通类型
i32
),它将返回一个普通类型
Vec
!它也称为类型构造函数,因为它用于构造类型。我们甚至可以更进一步:

* -> * -> *
这有点奇怪,因为它与非Haskell程序员有关,读起来很奇怪。但这意味着:给我两种类型,我将返回一种类型。让我们考虑一个例子<代码>结果!
Result
类型构造函数将返回一个具体的类型
结果。

在某种程度上,Rust确实有一个看起来很像HKT的东西(请参阅Lukas的答案,了解它们是什么),尽管有一些可以说是笨拙的语法

首先,您需要为所需的指针类型定义接口,这可以使用泛型特征来完成。例如:

trait SharedPointer<T>: Clone {
    fn new(v: T) -> Self;
    // more, eg: fn get(&self) -> &T;
}
最后,我们可以使用它:

struct A;
struct B;

struct Foo<P: Param<A> + Param<B>> {
    a: <P as Param<A>>::Pointer,
    b: <P as Param<B>>::Pointer,
}

impl<P: Param<A> + Param<B>> Foo<P> {
    fn new(a: A, b: B) -> Foo<P> {
        Foo {
            a: <P as Param<A>>::Pointer::new(a),
            b: <P as Param<B>>::Pointer::new(b),
        }
    }
}

fn main() {
    // Look ma, we're using a generic smart pointer type!
    let foo = Foo::<RcParam>::new(A, B);
    let afoo = Foo::<ArcParam>::new(A, B);
}
结构A;
结构B;

struct Foothanks回答了这么长的问题!非常有趣。只有
语法对我来说似乎有点混乱,但我肯定会阅读关于itThanks的章节。很好地解释了这个问题。我认为真正的力量来自相关类型的类型省略。
trait SharedPointer<T>: Clone {
    fn new(v: T) -> Self;
    // more, eg: fn get(&self) -> &T;
}
trait Param<T> {
    type Pointer: SharedPointer<T>;
}
impl<T> SharedPointer<T> for Rc<T> {
    fn new(v: T) -> Self {
        Rc::new(v)
    }
}
impl<T> SharedPointer<T> for Arc<T> {
    fn new(v: T) -> Self {
        Arc::new(v)
    }
}
struct RcParam;
struct ArcParam;

impl<T> Param<T> for RcParam {
    type Pointer = Rc<T>;
}

impl<T> Param<T> for ArcParam {
    type Pointer = Arc<T>;
}
struct A;
struct B;

struct Foo<P: Param<A> + Param<B>> {
    a: <P as Param<A>>::Pointer,
    b: <P as Param<B>>::Pointer,
}

impl<P: Param<A> + Param<B>> Foo<P> {
    fn new(a: A, b: B) -> Foo<P> {
        Foo {
            a: <P as Param<A>>::Pointer::new(a),
            b: <P as Param<B>>::Pointer::new(b),
        }
    }
}

fn main() {
    // Look ma, we're using a generic smart pointer type!
    let foo = Foo::<RcParam>::new(A, B);
    let afoo = Foo::<ArcParam>::new(A, B);
}