如何在Rust中编写可接受简化闭包并自动推导完整泛型类型的构造函数?
如何在Rust中编写可接受简化闭包并自动推导完整泛型类型的构造函数?
嘿,我完全懂你遇到的困扰——你定义的Thing结构体要求闭包必须接受两个参数并返回对应的元组,但每次写完整的闭包实在有点繁琐,想整个便捷构造函数让用户只传单个参数的闭包就能搞定,结果编译器还不给过,对吧?别着急,咱们一步步来解决这个问题。
首先先把你的Thing结构体补全(看你代码里的_dummy应该是漏了B的占位符):
use std::fmt::Debug; use std::marker::PhantomData; struct Thing<A, B, F> where A: Debug, B: Debug, F: Fn(A, B) -> (A, B), { f: F, _dummya: PhantomData<A>, _dummyb: PhantomData<B>, // 补全B类型的占位符 }
接下来先给它实现最基础的构造函数,用来接受符合要求的完整双参数闭包:
impl<A, B, F> Thing<A, B, F> where A: Debug, B: Debug, F: Fn(A, B) -> (A, B), { // 原始构造函数:只接受标准的双参数闭包 pub fn new(f: F) -> Self { Self { f, _dummya: PhantomData, _dummyb: PhantomData, } } }
现在重点来了——实现咱们要的便捷构造函数。核心思路就是:把用户传的单参数闭包包装成符合Thing要求的双参数闭包。比如用户只想处理第一个参数,那咱们就把原闭包包装成“处理第一个参数,第二个参数原样返回”的双参数闭包;同理如果只想处理第二个参数,就反过来。
咱们给Thing加两个关联函数,分别对应两种单参数闭包的场景:
// 便捷构造函数1:接受只操作第一个参数的闭包 impl<A, B, F> Thing<A, B, impl Fn(A, B) -> (A, B)> where A: Debug, B: Debug, F: Fn(A) -> A, { pub fn from_first_arg(f: F) -> Self { // 把单参数闭包包装成双参数的:处理A,返回新A+原B Self::new(move |a, b| (f(a), b)) } } // 便捷构造函数2:接受只操作第二个参数的闭包 impl<A, B, F> Thing<A, B, impl Fn(A, B) -> (A, B)> where A: Debug, B: Debug, F: Fn(B) -> B, { pub fn from_second_arg(f: F) -> Self { // 把单参数闭包包装成双参数的:处理B,返回原A+新B Self::new(move |a, b| (a, f(b))) } }
现在咱们来测试一下,看看是不是好用:
fn main() { // 用原始构造函数传完整闭包 let full_thing = Thing::new(|a: i32, b: String| (a + 5, format!("{}-processed", b))); println!("{:?}", (full_thing.f)(10, "test".to_string())); // 输出 (15, "test-processed") // 用便捷构造函数,只处理第一个参数 let first_thing = Thing::from_first_arg(|a: i32| a * 2); println!("{:?}", (first_thing.f)(3, "unchanged".to_string())); // 输出 (6, "unchanged") // 用便捷构造函数,只处理第二个参数 let second_thing = Thing::from_second_arg(|b: String| b.to_uppercase()); println!("{:?}", (second_thing.f)(7, "rust".to_string())); // 输出 (7, "RUST") }
这里要提一句:如果编译器没办法自动推导泛型类型(比如你只是创建Thing但暂时不用它),可能需要显式指定类型参数,比如:
// 显式指定A和B的类型 let explicit_thing = Thing::<i32, String, _>::from_first_arg(|a| a + 1);
这样就能完美解决你的问题了——用户可以按需传简化的单参数闭包,编译器也能自动推导泛型类型(或者在需要时显式指定),完全符合你的需求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

