Dart 中编译时的静态、最终和常量成员有什么区别?
what's the difference between static, final and const members at compile time in Dart?
正如标题所暗示的,Dart 中 static、final 和 const 在编译时有什么区别?
何时计算它们以及何时为每种类型分配内存?
大量使用静态变量会导致性能问题或 OOM 吗?
static
是声明class级成员(方法,字段,getters/setters)。
它们位于 class' 命名空间中。它们只能从 class 中访问(不是子 classes)或使用 class 名称作为前缀。
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;
}
}
static 变量不需要使用 class 的实例。
示例:
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!
}
A const 变量类似于 final
变量,因为它是不可变的(无法更改)。但是,const
值必须能够在编译时计算。 const
值也将被重复使用,而不是重新计算。
示例:
class MathClass {
const var section = 4;
const var examTime = DateTime.now(); // Error! Cannot be determined at compile time.
}
正如标题所暗示的,Dart 中 static、final 和 const 在编译时有什么区别?
何时计算它们以及何时为每种类型分配内存? 大量使用静态变量会导致性能问题或 OOM 吗?
static
是声明class级成员(方法,字段,getters/setters)。
它们位于 class' 命名空间中。它们只能从 class 中访问(不是子 classes)或使用 class 名称作为前缀。
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;
}
}
static 变量不需要使用 class 的实例。
示例:
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!
}
A const 变量类似于 final
变量,因为它是不可变的(无法更改)。但是,const
值必须能够在编译时计算。 const
值也将被重复使用,而不是重新计算。
示例:
class MathClass {
const var section = 4;
const var examTime = DateTime.now(); // Error! Cannot be determined at compile time.
}