Rust中如何定义返回Struct<Fn>类型实例的函数
问题原因
你写的fn some_function() -> A<Fn(i32)->i32>签名无法通过编译,核心原因如下:
Fn(i32) -> i32是特征(trait)而非具体类型,直接作为泛型参数使用时属于动态大小类型(DST),Rust要求函数返回值的内存大小必须在编译期可确定,这类无固定大小的类型无法直接作为返回值。- 所有闭包、具名函数都有独有的匿名类型,即使签名完全一致、都实现了
Fn(i32)->i32,彼此也是完全不同的类型。
可落地方案
根据你的使用场景选对应实现即可:
方案1:返回固定逻辑的可调用对象,零开销静态分发
如果函数只会返回同一种逻辑的闭包/具名函数,直接用impl Trait语法写返回值即可,编译期会自动推导具体类型,没有额外运行时开销:
// 原结构体定义保持不变 struct A<F: Fn(i32) -> i32> { func: F } // 返回固定闭包 fn some_function() -> A<impl Fn(i32) -> i32> { A { func: |x| x * 2 + 1 } } // 返回具名函数也可以 fn calc(x: i32) -> i32 { x - 3 } fn some_function2() -> A<impl Fn(i32) -> i32> { A { func: calc } }
方案2:需要按条件返回不同逻辑的可调用对象,动态分发
如果需要根据运行时分支返回逻辑不同、类型也不同的闭包,就用Box<dyn Fn(i32)->i32>作为泛型参数,通过堆分配和特征对象实现多态,会存在少量运行时开销:
fn some_function(need_add: bool) -> A<Box<dyn Fn(i32) -> i32>> { if need_add { A { func: Box::new(|x| x + 10) } } else { A { func: Box::new(|x| x * 10) } } }
注意:不要尝试直接返回
A<dyn Fn(i32)->i32>,dyn Fn本身是动态大小类型,必须通过Box这类固定大小的指针类型间接包裹才能作为返回值使用。
内容的提问来源于stack exchange,提问作者doki
相关产品推荐
相关产品推荐

