rust - 为什么具有默认值的泛型需要类型注释,而 Vec in nightly 会自动推断其分配器?

标签 rust

我正在尝试定义一个带有默认类型参数的结构,就像 Vec 在 Rust nightly 中使用其分配器工作一样。但是,正如其他答案和 Rust 论坛中所解释的那样,类型推断并不是这样工作的:

use std::marker::PhantomData;

struct Foo<X: Copy = i32> {
    x: PhantomData<X>
}

impl<X: Copy> Foo<X> {
    fn new() -> Foo<X> {
        Foo {
            x: PhantomData
        }
    }
}

fn main() {
    // type annotations needed
    let foo = Foo::new();
    
    // works??
    let mut bar = Vec::new();
    bar.push(42); // to let Rust infer T.
}

我的问题不是为什么 Foo::new() 不能编译,而是为什么 Vec::new() 仍然可以。如果我删除 Foo::new(),文件会编译。据我所知,支持分配器的 Vec 的新定义应该已经破坏了几乎所有代码。

理想情况下,答案会指向 rustc 中进行此豁免的代码(如果是的话)。

最佳答案

impl in which fn new is definedT 上通用, 但不是 A :

impl<T> Vec<T> {
    pub const fn new() -> Self {
        // ...
    }
}

A默认值为 Global , 这实现了一个 new Vec<T, Global> 的函数.它没有实现 new任何其他分配器的功能。所以Vec::new将始终创建一个新的 Vec<_, Global> .

事实A有一个默认值实际上是相切的;解决 Vec::new 时没有考虑到这一点.

你可以制作Foo以同样的方式工作:

impl Foo<i32> {
    fn new() -> Self {
        Foo { x: PhantomData }
    }
}

请注意,在本例中为 new将始终创建一个 Foo<i32> , 如果你想要一个创建不同类型的 Foo 的函数,您需要创建一个不同名称的函数,就像 Vecnew_in用于指定与 Global 不同的分配器.

关于rust - 为什么具有默认值的泛型需要类型注释,而 Vec in nightly 会自动推断其分配器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67949615/

相关文章:

rust - 在 Rust 中的堆上创建一个固定大小的数组

rust - 如何在类似函数的过程宏中计算类型的实例并返回它?

rust - impl block 不需要泛型参数的生命周期限制

rust - 具有特征边界的通用结构字段

rust - 带有指向自身数据的切片的结构

rust - 什么时候 `std::process::exit` O.K.使用?

multithreading - web::block() 失败并显示 "` NonNull<pq_sys::pg_conn >` cannot be shared between threads safely"

compilation - 我不明白借贷是如何运作的

reflection - 如何从 Rust 函数内部检查它是直接调用还是由 C# 代码中的 Invoke() 调用?

rust - 如何实现迭代器产生可变引用