Dart类原生getter与extension扩展getter空对象调用差异原因问询
问题现象原因解释
该差异由Dart中类实例成员与扩展成员的底层调度逻辑不同导致:
- 示例运行在未开启空安全的Dart环境下,声明后未初始化的
Person person默认值为null。 - 调用类原生getter
isEmpty时,Dart对类实例成员采用动态派发规则:只有非空的类实例才能调度自身的成员属性/方法。当调用者为null时,null本身没有定义isEmptygetter,直接抛出NoSuchMethodError。 - 调用扩展属性
isEmptyByExt时,Dart对扩展成员采用静态派发规则:扩展本质是静态顶层函数的语法糖,调用时会把调用者作为参数直接传入扩展内部。未开空安全时null可以匹配Person类型的参数约束,此时扩展内的this就是传入的null,this == null判断直接返回true,全程不需要在null对象上调度成员,因此不会抛出异常。
空安全场景补充
若开启Dart空安全,未初始化的不可空类型Person person;会直接编译报错,必须声明为可空类型Person? person;。此时原声明为on Person的扩展无法被null调用,只有将扩展声明改为on Person?才能匹配可空类型的调用,行为逻辑和上述非空安全场景一致。
内容的提问来源于stack exchange,提问作者Liu Silong
相关产品推荐
相关产品推荐

