关于rust元编程的思考

问题来源

java是我比较熟悉的语言,在学习rust的时候我总会思考他和java有什么不同。众所周知java依靠反射、注解能够完成依赖注入、动态代理、AOP等很多非常强有力的能力,配合这些元编程的能力能够使得代码架构变得更加优雅。

rust作为一门更接近C++/C的系统编程语言,对于它的优点我们自然都已经十分清楚。让我好奇的是,rust没有反射、注解及其衍生的动态代理、AOP能力,它的元编程体验会是如何的呢?

思考汇总

关于反射

rust和java其实都可以完成反射的能力,重点是是否为运行时反射(runtime refelection)。这块社区是有过讨论的,参考:Rust反射之Any

rust的设计理念都是尽量在编译时解决掉所有问题。rust是性能优先,java则是易用性、功能优先。java采用运行时反射,元数据都在方法区,运行时可以获取元信息来完成一些能力,例如对象的序列化和反序列化。rust则是编译时反射,在编译的时候直接生成序列化和反序列化的代码,运行时不需要做额外的工作,性能更好。

总结的话:

  • rust: 性能优先,编译时根据依赖的元信息即可确定好要生成的代码,无需用户在运行时依赖元信息去做处理。
  • java: 易用性、功能优先。直接将元信息放到内存,需要的时候获取。这样会特别灵活、开发者使用起来也特别简单。

关于AOP

rust本身没提供AOP机制,但是通过宏、trait,很多类似元编程的能力可以在编译期通过代码生成来完成。rust也有一些AOP库的封装,不过好像不太流行。总的来说,在java中能做到的事情,在rust中也可以做到,但是会别扭很多,因为语言层面缺乏内置机制,开发者要实现类似功能有很多工作要做。

所以,如果你是个深度依赖AOP、反射等能力来做架构设计和代码实现的,用rust会有很多不习惯。在rust中你得依靠trait、宏、属性等机制来达成类似的事情。

其他补充

我在rust社区也有一个提问,有兴趣可以看下:Does rust need AOP as a system programming language?

总结

rust和java的设计理念是有很大差异的,专注于性能以及编译时确定自然也会带来一些额外的性质。很多trade-off都是如此,没有什么是万能的,我们只是选择合适的而已。