Dart的宏取消了,期待3年的功能,说没就没了?

哈喽,我是老刘

就在刚刚结束的Fluttercon EU 2025上,Google Dart团队宣布:投入数年时间、无数工程师心血的宏功能开发,彻底停止了!

这不是延期,不是推迟,而是直接砍掉!

这意味着从2022年开始,Dart团队投入的所有资源、所有原型开发、所有技术攻关,全部归零。

作为一个六七年的Flutter老兵,同时也是从C/C++时代走过来的开发者,我对这个消息的震惊程度,可能比很多人都要强烈。

因为我太清楚宏功能对于大型项目意味着什么了。

在C/C++的世界里,宏是大型项目的救命稻草。

在Flutter的世界里,由于禁用了反射,我们失去了太多便利性。

比如JSON的自动解析,比如依赖注入,比如代码生成...

这些功能现在只能通过build_runner这种笨重的方式来实现。

而宏,本来应该是更优雅、更高效的解决方案。

甚至比反射还要好!

但现在,这一切都没了。

宏功能到底是个啥?

说到宏,很多Flutter开发者可能一脸懵逼。

毕竟Dart从来没有过这个功能。

但对于我这种从C/C++时代走过来的老兵,宏简直就是编程界的"变形金刚"。

简单来说,宏就是一种在编译时告诉编译器"怎么处理代码"的机制。

想象一下,你写了一段重复性很高的代码,比如为每个数据类都要写getter、setter、toString、hashCode...

宏可以让你只写一行注解,编译器自动帮你生成这些代码。

举个例子,在Rust中,你只需要写:

c 复制代码
#define DECLARE_GETTER_SETTER(type, name) \
private: \
    type name##_; \
public: \
    type get##name() const { return name##_; } \
    void set##name(const type& value) { name##_ = value; }

class User {
    DECLARE_GETTER_SETTER(std::string, Name)
    DECLARE_GETTER_SETTER(int, Age)
};

一个简单的宏定义,就能自动生成getter和setter方法。

如果没有宏,你得手写几十行代码!

在Flutter中,如果有了宏,我们可能只需要:

dart 复制代码
@JsonSerializable()
class User {
  final String name;
  final int age;
}

编译器就自动生成fromJson、toJson方法。

不用再忍受build_runner那龟速般的代码生成了!

这就是宏的第一个作用:减少代码重复,提高可维护性。

但宏的威力远不止于此。

更进一步,宏可以在编程语言的基础上形成一套DSL(领域特定语言)。

比如在Rust中,你可以用宏创建自己的"小语言",让代码更贴近业务逻辑。

在C/C++中,宏更是大型项目的标配。

Linux内核、Chrome浏览器、各种游戏引擎...

哪个不是宏满天飞?

因为宏能让复杂的系统变得简洁、可读、易维护。

这就是为什么我对Dart宏功能如此期待的原因。

Flutter项目越来越大,代码重复越来越多,build_runner越来越慢...

宏本来应该是解决这一切问题的银弹。

揭秘真相:为什么Google要砍掉这个"万能神器"?

但是,理想很丰满,现实很骨感。

Google为什么要砍掉这个看起来如此完美的功能?

答案比你想象的更复杂。

第一个原因:技术野心太大,想一口吃成胖子

这里有个关键细节,很多人都忽略了。

Dart团队追求的不是简单的语法级宏,而是"深度语义内省"。

什么意思?

简单的宏只是文本替换,就像C/C++的#define一样。

但Dart团队想要的是能够理解代码语义的智能宏。

比如,宏不仅要知道你定义了一个类,还要知道这个类的继承关系、泛型参数、注解信息...

甚至要在代码还在修改的时候,就能进行语义分析!

这就像是要求一个翻译不仅要会翻译文字,还要理解文化背景、历史典故、双关语...

技术难度直接从"困难"跳到了"地狱级"。

对比一下其他语言:

Rust的宏从简单的macro_rules!开始,逐步演进到过程宏。

C++的宏虽然强大,但本质上还是预处理器的文本替换。

而Dart想要一步到位,直接做最复杂的语义宏。

结果就是:每解决一个问题,就冒出三个新问题。

第二个原因:性能噩梦,开发体验杀手

这是最致命的问题。

Dart团队发现,深度语义内省会带来巨大的编译时成本。

IDE的代码补全变慢了。

静态分析变慢了。

最要命的是,热重载也变慢了!

热重载是Flutter的杀手锏功能,如果连这个都受影响,那宏功能就是在自掘坟墓。

想象一下,你改了一行代码,本来1秒钟就能看到效果。

现在因为宏的语义分析,要等5秒、10秒...

开发者会疯掉的!

这就像是为了让汽车更智能,结果把发动机搞得越来越重,最后车都开不动了。

第三个原因:无底洞效应,看不到终点

最让Dart团队绝望的可能是,这个问题似乎没有边界。

每当他们以为快要解决所有问题时,就会发现新的技术挑战。

性能优化了一点,又发现内存占用暴增。

内存问题解决了,又发现并发编译有问题。

并发问题解决了,又发现增量编译逻辑有bug...

就像是在玩打地鼠游戏,永远打不完。

团队投入了数年时间,烧了无数资源,却看不到成功的曙光。

继续投入,可能是无底洞。

停止开发,至少能把资源用在其他地方。

第四个原因:机会成本太高

这是最现实的考量。

Dart团队的人力资源是有限的。

把这些顶级工程师用在宏功能上,就意味着其他功能得不到开发。

比如性能优化、新的语言特性、工具链改进...

这些可能对开发者更有实际价值。

而且,宏功能即使做出来了,也不是所有开发者都会用。

但性能优化、工具链改进,每个开发者都能受益。

从投入产出比来看,砍掉宏功能可能是更明智的选择。

第五个原因:替代方案基本够用

说实话,虽然build_runner慢一点,但它能解决大部分问题。

json_annotation、freezed、retrofit...

这些第三方库已经形成了相对成熟的生态。

虽然不如宏那么优雅,但至少是可用的。

而且,Dart团队承诺会大幅优化build_runner的性能。

如果build_runner能快10倍,那宏功能的必要性就大大降低了。

这就像是,虽然没有了超级跑车,但普通汽车也能满足日常需求。

看到这里,你可能会问:那其他语言是怎么做到的?

答案很简单:它们没有Dart这么大的野心。

Rust的宏虽然强大,但它是逐步演进的,而且性能要求没有Dart这么苛刻。

C++的宏更是简单粗暴,根本不考虑语义分析。

只有Dart,想要在保持极致性能的同时,实现最复杂的语义宏。

这就像是想要造一辆既能飞又能潜水还要比跑车快的交通工具。

Dart团队的Plan B能拯救开发者吗?

虽然宏功能没了,但Dart团队并没有坐以待毙。

他们拿出了一套"Plan B",试图用其他方式解决开发者的痛点。

说实话,这套方案虽然不如宏那么性感,但可能更实用。

第一招:专门的数据类特性

Dart团队承诺会推出专门针对数据类的语言特性。

什么意思?

就是不用宏,也能优雅地处理数据序列化、比较、拷贝这些常见操作。

比如,未来可能会有这样的语法:

dart 复制代码
data class User {
  final String name;
  final int age;
}

只要加个data关键字,编译器就自动生成toString、hashCode、operator==、copyWith等方法。

这个思路其实很聪明。

与其搞复杂的宏系统,不如针对最常见的用例,直接在语言层面提供支持。

Kotlin就是这么做的,效果相当不错。

第二招:build_runner性能大提升

这是最实际的改进。

Dart团队承诺会对build_runner进行彻底重构,目标是10倍性能提升!

如果真能做到,那现在的痛点就基本解决了。

想象一下,原来需要30秒的代码生成,现在只要3秒。

原来需要5分钟的全量构建,现在只要30秒。

虽然还是没有宏那么优雅,但至少不会让人抓狂了。

而且,build_runner的生态已经很成熟,不需要重新学习。

第三招:Augmentations功能

这是最有意思的一个方案。

Augmentations可以理解为"宏的精简版"。

它不能做复杂的语义分析,但能解决80%的常见需求。

比如,你可以用Augmentations给现有的类添加方法:

dart 复制代码
augment class User {
  String get displayName => '$name ($age岁)';
}

这样就能在不修改原始类的情况下,扩展功能。

虽然没有宏那么强大,但对于大部分场景已经够用了。

第四招:社区方案的官方加持

Dart团队还承诺会更深度地支持社区方案。

比如freezed、json_annotation、retrofit这些库,可能会得到官方的性能优化支持。

甚至可能直接集成到Dart SDK中。

这样一来,虽然还是第三方库,但体验会更接近原生功能。

给开发者的实用建议

面对这个现实,我们该怎么办?

1. 拥抱现有方案,别等了

如果你还在等宏功能,可以停止了。

freezed + json_annotation的组合已经很成熟,完全可以满足大部分需求。

虽然代码生成慢一点,但至少稳定可靠。

2. 关注build_runner的性能优化

Dart团队承诺的10倍性能提升,如果真能实现,会彻底改变游戏规则。

建议密切关注相关更新,第一时间升级。

3. 学习Augmentations

这个功能虽然还在实验阶段,但很有前景。

提前了解语法和用法,等正式发布时就能立即上手。

4. 优化现有的代码生成流程

在等待官方优化的同时,我们也可以优化自己的构建流程。

比如使用增量构建、并行构建、缓存机制等。

5. 保持开放心态

技术发展总是充满变数。

今天砍掉的功能,明天可能以另一种形式回归。

保持学习,保持适应,这是程序员的基本素养。

总结:完美往往是优秀的敌人

2007年,苹果发布第一代iPhone时,很多功能都不完美。

没有复制粘贴,没有多任务,甚至连3G都不支持。

但乔布斯说:"我们不是在做一个完美的产品,而是在做一个足够好的产品。"

Google这次砍掉宏功能的决定,虽然让无数开发者失望,但从工程角度来看,这是一个理性的选择。

技术团队花了3年时间,投入了大量资源,最终发现这条路走不通。

这时候果断止损也是需要巨大勇气的。

我们总是追求技术的完美,希望有一个银弹能解决所有问题。

但现实是,大部分时候"够用"比"完美"更重要。

freezed + json_annotation虽然不够优雅,但它们稳定、可靠、生态成熟。

build_runner虽然慢,但它能解决问题,而且还在持续优化。

在技术的世界里,我们经常会遇到这样的选择:

是追求理论上的完美,还是接受现实中的妥协?

Google这次的决定告诉我们:有时候放弃也是一种智慧。

Dart生态不会因为没有宏而停滞不前。

相反,它会在现有的基础上继续演进,找到更实用的解决方案。

这或许就是工程思维和学术思维的区别。

学术追求完美,工程追求可行。

在技术的世界里,最大的勇气不是开始一个项目,而是知道何时该放手。

Google这次的决定,或许正是这种勇气的体现。

如果看到这里的同学对客户端或者Flutter开发感兴趣,欢迎联系老刘,我们互相学习。 私信免费领老刘整理的《Flutter开发手册》,覆盖90%应用开发场景。 可以作为Flutter学习的知识地图。

------ laoliu_dev

相关推荐
_大学牲7 小时前
Flutter 之魂 GetX🔥(三)深入掌握依赖管理
前端·flutter
西西学代码8 小时前
Flutter---showCupertinoDialog
java·前端·flutter
爱吃水蜜桃的奥特曼8 小时前
玩Android Flutter版本,通过项目了解Flutter项目快速搭建开发
android·flutter
西西学代码10 小时前
Flutter---带输入框的对话框
flutter
_阿南_10 小时前
flutter在Xcode26打包的iOS26上全屏支持右滑的问题
flutter·ios·xcode
西西学代码11 小时前
Flutter---坐标网格图标
前端·javascript·flutter
zhifanxu11 小时前
flutter布局调试
flutter
Zender Han1 天前
Flutter 实现人脸检测 — 使用 google_mlkit_face_detection
android·flutter·ios
西西学代码1 天前
Flutter---默认程序(计数器)
flutter