You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中字段赋值未按预期生效的原因及解决方法

问题分析与解决

代码示例

class FooBase {
  String? name;

  FooBase({required this.name});
}
class Foo extends FooBase{
  final String name;

  Foo({required this.name}) : super(name: name);
}

void main() {
  final foo = Foo(name: 'foo');
  final fooForm = foo;
  fooForm.name = 'bar';
  print(fooForm.name);
}

为什么实际打印"foo"?

因为Foo类中定义了final类型的同名成员变量name,它会隐藏父类FooBase的name属性:

  1. 执行fooForm.name = 'bar'时,由于子类Foo的name是final不可赋值,Dart会隐式给父类FooBase的name赋值为'bar';
  2. 但打印fooForm.name时,读取的是子类Foo中final的name(值始终是初始化时的'foo'),父类的name被隐藏无法直接访问,所以最终输出'foo'。

如何修改使其打印"bar"?

最合理的方案是移除子类中重复定义的name,让子类直接继承使用父类的name属性,避免成员隐藏问题:

修改后的代码:

class FooBase {
  String? name;

  FooBase({required this.name});
}
class Foo extends FooBase{
  // 移除子类的name定义,通过super复用父类的构造参数
  Foo({required super.name});
}

void main() {
  final foo = Foo(name: 'foo');
  final fooForm = foo;
  fooForm.name = 'bar';
  print(fooForm.name); // 输出"bar"
}

如果确实需要子类保留独立的name成员,也可以通过显式访问父类属性的方式修改(不推荐,易造成混淆):

void main() {
  final foo = Foo(name: 'foo');
  final fooForm = foo;
  // 显式转换为父类类型后赋值
  (fooForm as FooBase).name = 'bar';
  // 打印父类的name属性
  print((fooForm as FooBase).name); // 输出"bar"
}

内容的提问来源于stack exchange,提问作者TSR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:16:00