【问题标题】:what's the difference between static, final and const members at compile time in Dart? [closed]Dart 编译时的静态、最终和常量成员有什么区别? [关闭]
【发布时间】:2019-05-25 14:18:09
【问题描述】:

如标题所示,Dart 中编译时的 static、final 和 const 有什么区别?

它们何时计算以及何时为每种类型分配内存? 大量使用静态变量会导致性能问题或 OOM 吗?

【问题讨论】:

标签: dart flutter access-modifiers


【解决方案1】:

static 是声明类级别的成员(方法、字段、getter/setter)。 它们在类的命名空间中。它们只能在类(而不是子类)内或以类名作为前缀访问。

class Foo {
  static bar() => print('bar');

  void baz() => bar(); // ok
}

class Qux extens Foo {
  void quux() => bar(); // error. There is no `bar()` on the `Qux` instance
}

main() {
  var foo = Foo();
  foo.bar(); // error. There is no `bar` on the `Foo` instance.
  Foo.bar(); // ok
}

const 用于编译时常量。 Dart 允许一组有限的表达式来计算编译时间常数。 const 实例已规范化。这意味着多个const Text('foo')(具有相同的'foo' 参数值)被规范化,并且无论此代码在您的应用中出现的位置和频率,都只会创建一个实例。

class Foo {
  const Foo(this.value);

  // if there is a const constructor then all fields need to be `final`
  final String value;
}
void main() {
  const bar1 = Foo('bar');
  const bar2 = Foo('bar');
  identical(bar1, bar2); // true 
}

final 只是意味着它只能在声明时分配。

例如字段,这意味着在字段初始值设定项中,通过使用this.foo 分配的构造函数参数,或在构造函数初始值设定项列表中,但在执行构造函数主体时不再存在。

void main() {
  final foo = Foo('foo');
  foo = Foo('bar'); // error: Final variables can only be initialized when they are introduced
}

class Foo {
  final String bar = 'bar';
  final String baz;
  final String qux;

  Foo(this.baz);
  Foo.other(this.baz) : qux = 'qux' * 3;
  Foo.invalid(String baz) {
  // error: Final `baz` and `qux` are not initialized
    this.baz = baz;         
    this.qux = 'qux' * 3;
  }
}

【讨论】:

  • 啊哈,我想我明白了。这是否意味着 const 和 static 成员都在构建时分配了内存,而实例成员在创建实例时分配?
  • 据我所知,静态成员在首次访问时被延迟初始化,这意味着它们是在运行时分配的,但你可以拥有static const ;-) static 就像一个顶级字段(在任何函数或类之外)仅使用类名作为附加命名空间。
  • 这是一个很好的解释,谢谢!
【解决方案2】:

静态变量不需要使用类的实例。

例子:

class Math {
  static var double staticPi = 3.14;
  double var pi = 3.14;
}

class ClassThatUsesMath {
  print(Math.staticPi);

  // Non-static variable must initialize class first:
  Math math = Math();
  print(math.pi);
}

一个final变量的值在赋值后就不能改变了。

例子:

class Math {
  final var pi = 3.14;
  pi = 3.1415;  // Error!
}

const 变量类似于final 变量,因为它是不可变的(无法更改)。但是,const 值必须能够在编译时计算。 const 值也将被重复使用,而不是重新计算。

例子:

class MathClass {
  const var section = 4;
  const var examTime = DateTime.now();  // Error! Cannot be determined at compile time.
}

【讨论】:

  • 在第一个示例中,我是否可以将 staticPis 值更改为 2.72,并且该值将持续到程序终止?如果我创建 2 个 Math 对象,我可以更改其中一个对象的 staticPi 还是静态变量不是实例的成员?
  • 是的;静态变量属于类,而不是实例,因此从任何地方更改变量都会在应用程序生命周期中使用的任何其他地方更改它。
猜你喜欢
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
相关资源
最近更新 更多