gpt4 book ai didi

rust - 将泛型函数作为参数传递

转载 作者:行者123 更新时间:2023-11-29 07:46:13 35 4
gpt4 key购买 nike

我希望能够将通用函数传递给另一个函数(在本例中为闭包),而不会丢失所传递函数的“通用性”。由于这是一个相当复杂的陈述,这里有一个例子:

use std::fmt::Debug;

fn test<F, I: Debug>(gen: F) where F: Fn(fn(I) -> I) -> I {
fn input<I: Debug>(x: I) -> I {
x
}

println!("{:?}", gen(input));
}

fn main() {
test(|input| {
input(10);
input(10.0)
});
}

这不会编译,因为 input 的值是类型推断的,不再是通用的。

完整错误:

<anon>:14:15: 14:19 error: mismatched types:
expected `_`,
found `_`
(expected integral variable,
found floating-point variable) [E0308]
<anon>:14 input(10.0)
^~~~

在 rust 中这样的事情可能吗?

编辑:

根据给出的解决方案,我使用以下方法解决了类似的问题:

#![feature(unboxed_closures)]
#![feature(fn_traits)]

use std::ops::Fn;
use std::ops::Add;
use std::ops::FnMut;

use std::fmt::Debug;

struct Builder;

impl Builder {
pub fn build<A: Add<B>, B: Add<A>>(&self) -> fn(A, B) -> <A as std::ops::Add<B>>::Output {
fn c<A: Add<B>, B: Add<A>>(a: A, b: B) -> <A as std::ops::Add<B>>::Output {
a + b
}

return c;
}
}

impl<A: Add<B>, B: Add<A>> Fn<(A, B)> for Builder {
extern "rust-call" fn call(&self, args: (A, B)) -> <A as std::ops::Add<B>>::Output {
let (a1, a2) = args;
self.build()(a1, a2)
}
}

impl<A: Add<B>, B: Add<A>> FnMut<(A, B)> for Builder {
extern "rust-call" fn call_mut(&mut self, args: (A, B)) -> <A as std::ops::Add<B>>::Output {
let (a1, a2) = args;
self.build()(a1, a2)
}
}

impl<A: Add<B>, B: Add<A>> FnOnce<(A, B)> for Builder {
type Output = <A as std::ops::Add<B>>::Output;
extern "rust-call" fn call_once(self, args: (A, B)) -> <A as std::ops::Add<B>>::Output {
let (a1, a2) = args;
self.build()(a1, a2)
}
}

fn test<F, I: Debug>(gen: F) where F: Fn(Builder) -> I {
let b = Builder;
println!("{:?}", gen(b));
}

fn main() {
test(|builder| {
builder(10, 10);
builder(10.1, 10.0)
});
}

最佳答案

如前所述,不幸的是调用在调用点是单态的,所以你不能传递泛型函数,你只能传递泛型函数的单态版本。

然而,您可以传递的是函数构建器:

use std::fmt::Debug;

struct Builder;

impl Builder {
fn build<I: Debug>(&self) -> fn(I) -> I {
fn input<I: Debug>(x: I) -> I { x }
input
}
}

fn test<F, T: Debug>(gen: F)
where F: Fn(Builder) -> T
{
let builder = Builder;
println!("{:?}", gen(builder));
}

fn main() {
test(|builder| {
builder.build()(10);
builder.build()(10.0)
});
}

Builder 能够根据需要生成 input 的实例。

关于rust - 将泛型函数作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37606035/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com