从源码寻找dart的语法糖,如果学会利用将让你的代码看起来更加有水平,相信领导会给对你刮目相看,最近看了framework源码总结了一些少用但却非常实用的语法糖。
一、方法的进一步封装
方法中有方法,如widget的更新源码
List<Element> updateChildren(List<Element> oldChildren, List<Widget> newWidgets, { Set<Element>? forgottenChildren, List<Object?>? slots }) {
assert(slots == null || newWidgets.length == slots.length);
//方法内嵌方法
Element? replaceWithNullIfForgotten(Element child) {
return forgottenChildren != null && forgottenChildren.contains(child) ? null : child;
}
//方法内嵌方法
Object? slotFor(int newChildIndex, Element? previousChild) {
return slots != null
? slots[newChildIndex]
: IndexedSlot<Element?>(newChildIndex, previousChild);
}
while ((oldChildrenTop <= oldChildrenBottom) && (newChildrenTop <= newChildrenBottom)) {
//调用内嵌方法
final Element? oldChild = replaceWithNullIfForgotten(oldChildren[oldChildrenTop]);
final Widget newWidget = newWidgets[newChildrenTop];
assert(oldChild == null || oldChild._lifecycleState == _ElementLifecycle.active);
if (oldChild == null || !Widget.canUpdate(oldChild.widget, newWidget)) {
break;
}
//调用内嵌方法
final Element newChild = updateChild(oldChild, newWidget, slotFor(newChildrenTop, previousChild))!;
assert(newChild._lifecycleState == _ElementLifecycle.active);
newChildren[newChildrenTop] = newChild;
previousChild = newChild;
newChildrenTop += 1;
oldChildrenTop += 1;
}
}
dart允许方法内嵌方法,但内嵌的方法只能在方法内部调用,不能在外部被使用
二、定义类的同时重命名类名
//定义一个新的别名RxNotifier
class RxNotifier<T> = RxInterface<T> with NotifyManager<T> ;
//等同于
class RxNotifier<T> extends RxInterface<T> with NotifyManager<T> {
}
如果想要给类起一个别名,可用=来重新定义并使用
三、构造函数的使用
dart的构造函数都会默认实现call()方法
class InternalFinalCallback<T> {
ValueUpdater<T>? _callback;
InternalFinalCallback({ValueUpdater<T>? callback}) : _callback = callback;
//默认会有call()方法,这里重写了call()方法
T call() => _callback!.call();
}
//创建一个InternalFinalCallback的对象。
final onStart = InternalFinalCallback<void>();
void _onStart() {
if (_initialized) return;
onInit();
_initialized = true;
}
void $configureLifeCycle() {
_checkIfAlreadyConfigured();
//传递方法给onStart对象的_callback变量
onStart._callback = _onStart;
onDelete._callback = _onDelete;
}
S _startController<S>({String? tag}) {
if (i is GetLifeCycleBase) {
//此时可以通过这个方式进行调用,默认调用call()方法。对象后面加()
i.onStart();
}
return i;
}
流程梳理
- 首先会定义一个InternalFinalCallback类,内部重写了call()方法,其实默认都会调用
- 然后将_onStart方法传递给onStart的_callback方法变量
- 此时如果直接调用onStart()则默认会执行call()方法。call()方法是对象通过对象()这种方式调用
四、方法默认返回值(void)
在定义方法的时候,如果返回默认值,理论上可以不加void返回类型,但如果不加的话dart引擎会默认加一行return null,如果没有返回值,建议加void返回类型
void markAsDirty<S>({String? tag, String? key}) {
final newKey = key ?? _getKey(S, tag);
if (_singl.containsKey(newKey)) {
final dep = _singl[newKey];
if (dep != null && !dep.permanent) {
dep.isDirty = true;
}
}
}
//如果这么写,默认会在底部加一句return null
markAsDirty<S>({String? tag, String? key}) {
final newKey = key ?? _getKey(S, tag);
if (_singl.containsKey(newKey)) {
final dep = _singl[newKey];
if (dep != null && !dep.permanent) {
dep.isDirty = true;
}
}
return null;
}
五、定义构造函数
在定义构造函数时,可以通过:冒号的方式直接调用父类构造函数或给变量赋值
StatefulElement(StatefulWidget widget)
: _state = widget.createState(),
super(widget) {
......
}
六、函数的通用类型
我们在传递函数的时候,都会通过typedef定义一个函数,但其实每个函数本身就是一个对象,都继承自Function,通过typedef只是定义了他的别名,所以也可以直接使用函数的父类function作为参数进行传递
//定义一个add函数
int minus(int a, int b) => a+b;
handle(Function function){
print('handle: ${function(3, 2)}'); //打印function结果
}
void main(){
handle(minus); //调用handle并传递minus函数
}
//打印
handle: 1