大概是代码复健中的一篇文章,今年经历了太多感情经历,有机会的话会在内站写写,有半年没有写过一行代码了,再次打开VS Code和Android Studio已经感到非常陌生了,加上我一直对专业术语运用生疏,所以文章看起来奇怪的地方还请包涵。
2024年Google IO上Flutter开发团队演示了一个新功能,用于快速生成代码的需求,比如JSON序列化。他们说这是对开发者提出的要添加data class这一新特性的回应。确实在之前的开发过程中遇到很多处理数据模型时遇到很多问题,比如在特定环境下需要写深拷贝代码,还有同事有时候改了数据类型结构也不跑一遍build runner代码,然后自己写了一些乱七八糟的实现。build runner的运行效率也不尽如人意,所以我来试试看这个Macros。
怎么配置我就不说了,在官网可以找到。我读了一圈发现几个比较感兴趣的地方,比如他们称这种实现方式为“静态元编程”:
Metaprogramming refers to code that can do this—code that operates on other code as if it were data. It can take code in as parameters, reflect over it, inspect it, create it, modify it, and return it. Static metaprogramming means doing that work at compile-time. This avoids the safety, performance, and code size problems of runtime metaprogramming. Examples are the C preprocessor, C++ templates, Rust macros, Swift function builders, and compile-time execution in Zig.
总结一下就是有两点:“元编程”意思是把其他代码当数据处理,“静态”指的是编译时处理。那么让我们看看它是怎么处理的。
我们先创建一个看上去很多项目都会有的结构的类型……等下怎么有报错?
好吧,不支持枚举问题还是挺大的,希望正式发布前能加上。除此之外在数据代码层面的用法和@JsonSerializable 差不多,都是标上去就行,只是@JsonSerializable 还要再跑一遍build runner,这里的话直接立刻就能生成出来了,速度非常快(也是官方视频里提到的):
并且在前一张图片中我们可以看到在数据代码类中我们不需要import或者part任何其他东西。那么这是怎么做到的呢?我们可以看到生成出来的数据类中有一个augment关键字对其进行了标识。那么我们来看看augment是什么:
具体的定义和用法还是看链接的描述。简单来说它可以扩充一个类,它不像mixin和path文件一样只能扩充不能访问和修改,也不需要原类型是抽象类。它可以访问原类型的成员变量和方法并直接修改该类。然后你就可以在外部调用了:
而对其进行标注的@JsonCodable 是一个标识了关键字macro的类型:
在该类型中,我们需要定义如何从标记的类型或变量中生成我们需要的代码,在之后的文章中我会进行详细解释。