generics - fn 的可选泛型类型参数?
问题描述
我想要一个函数有一个可选的泛型类型参数来做这样的事情:
fn main() {
bar::<()>();
}
fn bar<F: Foo>() {
let x = some_computation();
if F != () {
let foo = F::new(x);
foo.foo();
}
}
trait Foo {
fn new(x: u64) -> Self;
fn foo(&self);
}
有没有办法有一个可选的类型参数?如果是这样,有没有办法检查类型参数是否存在于函数中?
我想答案是否定的,但是有可能用宏来做到这一点吗?
解决方案
通常,您不能为函数指定默认类型参数,也无法区分类型参数,除非通过 trait 上的方法。
最简单的解决方法是只使用两个函数,例如bar
and bar_with
,其中一个不接受类型参数,另一个接受一个类型参数:
// call with no type parameters
pub fn bar() {
let x = some_computation();
}
// call with type parameter
pub fn bar_with<F: Foo>() {
let x = some_computation();
let foo = F::new(x);
foo.foo();
}
如果函数足够复杂,您可以拥有两个函数都调用的私有辅助函数:
// call with no type parameters
pub fn bar() {
bar_inner(|_x| { /* do nothing */ })
}
// call with type parameter
pub fn bar_with<F: Foo>() {
bar_inner(|x| {
let foo = Foo::new(x);
foo.foo();
})
}
fn bar_inner<Func: FnOnce(u64)>(func: Func) {
let x = some_computation();
func(x);
}
或者,您可以使用为所有类型实现的附加特征Foo
和默认类型 ( ()
) 来解决此问题:
trait BarArg {
fn bar_inner(x: u64);
}
impl<F: Foo> BarArg for F {
fn bar_inner(x: u64) {
let foo = foo::new(x);
foo.foo();
}
}
impl BarArg for () {
fn bar_inner(_x: u64) {
// do nothing
}
}
fn bar<B: BarArg>() {
let x = some_computation();
B::bar_inner(x)
}
推荐阅读
- r - 如何使用函数 usmap 在 R 中更改州或县标签大小?
- python - Python pyodbc '只执行'
- html - CSS:当屏幕宽度高于某个值时,将按钮放置在 div 中右侧的最佳方法
- sql-server - 如何清除 SQL Server 的磁盘空间?
- c++ - 班级成员的顺序会影响访问速度吗?
- mysql - 如何在没有常规权限的情况下部署 laravel 应用程序
- php - 如何在 WordPress 页面上显示特定帖子?
- linux - 如何检查 Linux 中的 /etc/passwd 文件是否包含无效条目?
- lua - Monaco Editor - 为 Lua 添加 monarch 多行字符串标记
- omnet++ - LEACH CASTALIA 中的 PHY 模型