Dart 语言团队正在添加对主构造函数(primary constructors)的支持。这一功能很可能会随 Dart 3.13 一起发布。
这个特性并不稀奇,很多种主流语言都支持,而Dart也即将迎来它的主构造函数。
对于 Flutter 开发者来说,这意味着更简洁的 widget、更简洁的 model、更简洁的一切。
什么是主构造函数?
如果你了解过Kotlin、Swift、C#等开发语言,那你一定比较熟悉主构造函数(primary constructor),即使你可能没听说过这个词,但一看到你就瞬间明白了,比如:
Kotlin
kotlin
class User(
val name: String,
val age: Int
)
C#
C#
class User(string name, int age)
另外,Scala 也支持主构造函数。Swift 虽然在文档中没有使用 "primary" 这个词,但它采用了类似的语法。
回到问题:"什么是主构造函数?"
主构造函数(primary constructor)是直接声明在类定义本身的构造函数。
我们不再将字段和构造函数参数分开声明,而是直接在类头部将它们一起定义。
我们以前写一个Dart的类是这样式的:
dart
class User {
final String name;
final int age;
final bool isAdmin;
const User({
required this.name,
required this.age,
required this.isAdmin,
});
}
同样的类换用主构造函数来实现则变成了:
dart
class const User({
required final String name,
required final int age,
required final bool isAdmin,
});
构造函数参数会自动成为字段。
无需重复声明。
无需额外的构造函数代码块。
代码简洁度翻倍。
很显然,Dart对主构造函数的支持实在是有点太晚了,正如上面提到的,很多语言其实是有类似的特性,但怎么说呢?好饭还是有点怕晚,哈哈哈哈......
当然了,对于这种可以提升开发效率的特性,我是特别期待的,甚至在我看来主构造函数甚至是一个必备特性,但它也带来了一个小小的可读性问题。
以下是一个没有使用主构造函数的 Flutter widget 定义:
dart
class ProductCard extends StatelessWidget {
final String title;
final String subtitle;
final double price;
final String imageUrl;
final VoidCallback onTap;
final bool isFavorite;
final bool showDiscount;
final Color backgroundColor;
final EdgeInsets padding;
final TextStyle? titleStyle;
const ProductCard({
super.key,
required this.title,
required this.subtitle,
required this.price,
required this.imageUrl,
required this.onTap,
required this.isFavorite,
required this.showDiscount,
required this.backgroundColor,
required this.padding,
this.titleStyle,
});
@override
Widget build(BuildContext context) {
...
}
}
代码虽然冗长,但我们一眼就能看出 ProductCard 继承自 StatelessWidget。
现在是用主构造函数重写的同一个 widget。
dart
class ProductCard({
super.key,
required final String title,
required final String subtitle,
required final double price,
required final String imageUrl,
required final VoidCallback onTap,
required final bool isFavorite,
required final bool showDiscount,
required final Color backgroundColor,
required final EdgeInsets padding,
final TextStyle? titleStyle,
}) extends StatelessWidget {
@override
Widget build(BuildContext context) {
...
}
}
代码简洁度确实提升了,但我们需要往下看才能找到它的父类。当然也可能只是习惯问题吧。
我认为在不久的将来,主构造函数将成为 Flutter 代码的主流写法。
你觉得呢?
你觉得dart还有哪些地方值得提升?