Dart中“ var”类型与“ dynamic”类型之间的区别?


72

根据这篇文章

如您所知,dynamic(现在称为)是未提供静态类型注释时的替代类型。

那么,dynamic和之间有什么区别var?什么时候使用?

Answers:


88

动态类型是所有Dart对象的基础类型。在大多数情况下,您不需要显式使用它。

var是关键字,意思是“我不在乎要指出这里的类型”。Dart会将var关键字替换为初始值设定项类型,如果没有初始值设定项,则默认情况下将其保留为动态

如果您希望变量赋值在其生命周期内发生变化,请使用var

var msg = "Hello world.";
msg = "Hello world again.";

如果您希望变量赋值在其生命周期内保持不变,请使用final

final msg = "Hello world.";

使用final(自由地)将帮助您捕获不想要的情况下意外更改变量分配的情况。

请注意,对于对象,finalconst之间有很好的区别。 final不一定使对象本身不可变,而const却可以:

// can add/remove from this list, but cannot assign a new list to fruit.
final fruit = ["apple", "pear", "orange"];
fruit.add("grape");

// cannot mutate the list or assign a new list to cars.
final cars = const ["Honda", "Toyota", "Ford"];

// const requires a constant assignment, whereas final will accept both:
const names = const ["John", "Jane", "Jack"];

1
为什么还要使用var关键字?只需将其设为默认值即可,就像python一样。
Dev Aggarwal

2
↑我认为这会使编译器更快。
陈潭Đức

3
也许Dart 2改变了这一点(我不知道Dart 1)。这是一个非常古老的答案。在这种情况下,应对其进行更新。还要注意,在Dart 2中,如果var未初始化,则似乎是dynamic(您可以执行例如var foo; foo = "str; foo = 1;(或对象类型的)?)这一点值得澄清
。– Ixx

他甚至没有问有关final或const的问题。这是可接受的答案吗?
丹尼尔·维莱拉

49

DartPad中尝试一下

void main() {
  dynamic x = 'hal';
  x = 123;
  print(x);
  var a = 'hal';
  a = 123;
  print(a);
}

您可以更改x的类型,但不能更改a。


8
仅当您分配给变量时。您可以随时这样做:var a; a =“ hi”; a = 123; 那是合法的。
Ashwin Prabhu

27

动态的:可以更改变量的TYPE,并且可以稍后在代码中更改变量的VALUE。

var: 无法更改变量的TYPE,但可以稍后在代码中更改变量的VALUE。

最终: 无法更改变量的类型,并且以后在代码中也无法更改变量的值。

dynamic v = 123;   // v is of type int.
v = 456;           // changing value of v from 123 to 456.
v = 'abc';         // changing type of v from int to String.

var v = 123;       // v is of type int.
v = 456;           // changing value of v from 123 to 456.
v = 'abc';         // ERROR: can't change type of v from int to String.

final v = 123;       // v is of type int.
v = 456;           // ERROR: can't change value of v from 123 to 456.
v = 'abc';         // ERROR: can't change type of v from int to String.

5
仅当您初始化var v时。未经初始化,var v与动态v相同
Ashwin Prabhu

13

var与一样final,用于声明变量。它根本不是一种类型。

Dart非常聪明,可以在大多数情况下知道确切的类型。例如,以下两个语句是等效的:

String a = "abc"; // type of variable is String
var a = "abc";    // a simple and equivalent (and also recommended) way
                  // to declare a variable for string types

另一方面,dynamic是一种特殊类型,指示它可以是任何类型(aka类)。例如,通过将对象强制转换为dynamic,您可以调用任何方法(假设有一个方法)。

(foo as dynamic).whatever(); //valid. compiler won't check if whatever() exists
(foo as var).whatever(); //illegal. var is not a type

4
从技术上讲,第一个示例显示了两个不相等的语句。var a创建一个动态类型的变量。String a创建一个类型为String的变量。Dart编辑器可能会执行其他类型推断,在这种情况下,它会这样做,但是请记住,这是超出规范的行为。
塞斯·拉德

@SethLadd var a =“某些字符串”; 不会创建动态类型的变量,因为赋值运算符,a将具有固定的String类型(在此示例中)。
乔治2.0希望

10
var a ;
a = 123;
print(a is int);
print(a);
a = 'hal';
print(a is String);

当没有初始值定义时,var是动态的

var b = 321;
print(b is int);
print(b);
//b = 'hal'; //error
print(b is String);

如果使用初始值定义,则var在这种情况下为int。


4

为了阐明先前的一些答案,当您将变量声明为时dynamic,其类型会根据您为其分配的内容而变化。当您声明时var,类型一旦被分配就被设置,之后就不能更改了。

例如,以下代码:

dynamic foo = 'foo';
print('foo is ${foo.runtimeType} ($foo)');
foo = 123;
print('foo is ${foo.runtimeType} ($foo)');

在DartPad中运行时将返回以下结果:

foo is String (foo)
foo is int (123)

但是以下代码甚至无法编译:

var bar = 'bar';
print('bar is ${bar.runtimeType} ($bar)');
bar = 123; // <-- Won't compile, because bar is a String
print('bar is ${bar.runtimeType} ($bar)');

长话短说-dynamic如果要使用非类型变量,请使用它var;如果要使用具有分配给它的任何类型的类型变量,请使用。


3

在比较动态vs var时可以比较的方面之一是在同时使用带有初始化的var声明时考虑到行为,而在动态情况下则不可能更改类型。

但是dynamic vs var不是我要问的问题。我想问更多动态与对象之间的区别。

这是一个用对象而不是动态DO注释,指示允许任何对象。

一开始很难感觉到它,但是动态的我将涉及泛型类型参数。


2

无论是在动态还是在var中,变量都可以保存任何数据类型的数据,即int,float,string等

如果将变量声明为动态变量甚至进行初始化,其类型也会随着时间而改变。https://dartpad.dev/中尝试以下代码

void main() {
  dynamic x = 'abc';
  x = 12345;
  print(x);

}

如果将变量声明为var,则一旦分配的类型就无法更改。

void main() {
  var x = 'abc';
  x = 12345;
  print(x);
}

上面的代码将导致错误,指出无法将'int'类型的值分配给'String'类型的变量-第3行

但是,如果您声明一个var而不进行初始化,那么它将变成动态的:

void main() {
  var x ;
  x = 'abc';
  x=12345;
  print(x);
}

0

一个dynamic变量可以改变他的类型和var种类不能改变。

例如 :

var myVar = 'hello';
dynamic myDynamicVar = 'hello';
myVar = 123; // not possible
myDynamicVar = 123; // possible


0

如果使用var,则无法更改变量的数据类型。但是,如果使用动态,则可以自由更改。对于前。

dynamic x = 12; // type: integer
x= "Hello world"; // type: string

如果使用var而不是dynamic进行相同操作,则将不会出现任何问题,因为您无法更改数据类型,因为在初始化时会自动将其分配给变量,因此会出现错误。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.