如何避免为Thing::builder()创建的构建器指定无用的占位类型?
如何避免为Thing::builder()创建的构建器指定无用的占位类型?
我懂你的痛点——本来构建器就是要延迟确定类型的,结果现在为了调用Thing::builder(),被迫加个完全没用的<u8>(或者其他占位类型),看着别扭还容易误导人。问题根源出在你把builder方法放在了针对泛型T的impl<T> Thing<T>块里,这意味着调用Thing::builder()时必须显式指定T,哪怕这个T后面根本用不上。
要解决这个问题很简单,只需要把builder方法移到非泛型的impl Thing块里,这样它就不再和具体的T绑定了:
struct Thing<T> { val: T, } // 这个impl块不指定<T>,是针对整个Thing结构体的关联函数 impl Thing { fn builder() -> ThingBuilder { ThingBuilder{} } } struct ThingBuilder { // 这里可以放构建器需要的各种状态字段 } impl ThingBuilder { // 泛型T在这里定义,从build方法的参数自动推导 fn build<T>(self, val: T) -> Thing<T> { Thing { val } } } fn main() { // 现在完全不需要占位类型了!编译器会从42u32自动推导T是u32 let thing = Thing::builder().build(42u32); println!("Thing value: {}", thing.val); }
这样修改后,Thing::builder()变成了整个Thing结构体的通用构建器入口,不需要提前指定任何类型。等到调用build方法时,编译器会根据你传入的val自动推导出Thing的泛型参数T,完美解决了无用占位类型的问题。
如果你的构建器需要在build之前设置一些和类型无关的配置,这个方案也完全适用——所有配置逻辑都放在ThingBuilder里,直到最后build时才确定最终的T类型。
内容来源于stack exchange
相关产品推荐
相关产品推荐

