如何在 Rust 函数中传递默认泛型类型?

4

我有一个名为cr的函数,我希望默认情况下通用类型 Tserde_json::Value。我该如何实现?

fn main() {
    cr()
}

fn cr<T = serde_json::Value>() {

}

我遇到了这个错误:在调用cr时无法推断函数声明的类型参数T。在cr函数中,我也遇到了这个错误:类型参数的默认值只允许出现在结构体、枚举、类型或trait定义中。

1
我认为错误消息告诉了你答案,即你不能在函数的类型参数上设置默认值。如果你想使用 serde_json::Value 调用 cr 函数,可以使用所谓的“turbofish”符号来指定:cr::<serde_json::Value>() - Neikos
一个泛型函数有默认类型参数是什么意思呢?类型参数总是由调用者提供,无论是显式地(使用尖括号)还是隐式地通过类型推断。唯一不需要提供类型参数的情况是泛型参数在函数的输入或输出中都没有被使用。 - Ivan C
“@IvanC 唯一不会有用的情况是,如果通用参数在函数的任何输入或输出中都没有被使用。”=> 这正是它有用的地方。带有特征约束的通用参数可用于函数体中,而无需成为输入或输出类型的一部分。例如,这可用于允许在函数的单元测试中模拟类型,而无需在生产代码中需要显式通用参数。 - Dominick Pastore
2个回答

2

正如错误所述,您不能在函数签名中使用默认类型参数。您可以通过包装类型来解决此问题。

use std::marker::PhantomData;

struct MyDefault;
struct Custom;

pub fn main() {
    Wrapper::cr(); //~ ERROR type annotations needed
    <Wrapper>::cr();

    Wrapper::<Custom>::cr();
    <Wrapper<Custom>>::cr();
}

struct Wrapper<T = MyDefault>(PhantomData<T>);

impl<T> Wrapper<T> {
    fn cr() {
        let _: T = todo!();
    }
}

推理不能猜测,因此需要一个类型提示来进行替换。例如,let x: SomeType<SubstType> 或者完全限定路径 <SomeType<SubstType>>::associated_item。在这里省略替代会触发 SomeType 中的默认替换。

1
这仍然会阻止您对cr()中的T执行任何有用操作,例如访问T的字段或调用T的函数,即使它们存在于默认类型或任何待给定类型上。或者我理解错了吗? - zertyz

-1
这里有个诀窍
type Echo<X = i32> = std::result::Result<X, String>;

fn test(x: Echo) {
    // ...
}

fn main() {
    test(Err("test".into()));
}


除了它根本不起作用之外。它强制使用泛型参数,而不是暗示它。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接