Dart中“var”和“dynamic”类型的区别?

时间:2012-09-14 00:08:24

标签: dart

根据this article

  

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

那么,dynamicvar之间有什么区别?何时使用?

12 个答案:

答案 0 :(得分:27)

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

var 是一个关键字,意思是“我不在乎注明这里的类型是什么。”,默认情况下保留动态

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

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

如果您期望变量分配在其生命周期内保持不变,请使用最终

final msg = "Hello world.";

使用 final (自由)将帮助您捕捉到在您不想要的时候意外更改变量赋值的情况。

请注意,对于对象, final const 之间存在细微差别。 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 :(得分:25)

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

var: 不能更改变量的类型,但是稍后可以在代码中更改变量的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.

答案 2 :(得分:7)

varfinal一样,用于声明变量。 一种类型。

Dart编辑器非常聪明,可以在某些情况下知道确切的类型。例如,如果您在首选项中打开了“使用类型检查的推断类型信息”,则以下两个语句在编辑器中类似:

var a = "abc";    // type of variable is dynamic,
                  // but editor can infer it is a string
String a = "abc"; // type of variable is String

另一方面,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

答案 3 :(得分:7)

DartPad中尝试:

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

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

答案 4 :(得分:2)

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。

答案 5 :(得分:1)

要弄清楚以前的答案,当您将变量声明为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

答案 6 :(得分:1)

dynamic和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);
}

答案 7 :(得分:1)

看看以前的答案,我希望这可以澄清/总结一切:

关键字 var、final 和 const。这些是声明一个变量(表明它的存在)(旁注:Declaration vs Initialization

然后是类型,如String、int、List、dynamic等。(类型表示变量应该持有什么样的值,这是针对type safety

通常,我们通过显式声明其类型来声明变量:

String a; // a is now a String type
int b; // b is now an int type

但我们也可以使用 var 关键字。默认情况下,这会将变量的类型设置为初始化时使用的任何类型。 (这称为type inference

var a = "hello"; // a is now a String type
var b = 5; // b is now an int type

现在当您尝试使用 var 关键字声明变量但不初始化值时会发生什么?它应该如何推断类型?嗯,还有一种类型叫做动态。这与通常的 String 或 int 不同,因为它允许为变量分配任何类型的值(通常会出现错误)。

String a = "hello"; // a is now a String type
// var a = "hello"; // Alternative way; same as the line above because its type is inferred to be String
a = 5 // error: A value of type 'int' can't be assigned to a variable of type 'String'

dynamic b; // b is now a dynamic type
b = "hello"; // still a dynamic type, but now its value is of type String  (You can use b.runtimeType to check)
b = 5; // dynamic type, but now its value is of type int

为了解决最初对文章引用的混淆,

<块引用>

您可能知道,当未提供静态类型注释时,动态(现在称为)是替代类型。

这只是意味着,如果您不显式声明其类型(您使用 var 声明变量)并且不进行初始化,它只会将其类型推断为动态:

var b; // b is now a dynamic type, the following will not have any errors.
b = "hello";
b = 5; 
b = true;

其他注意事项:

  • 不知道为什么人们开始谈论 final 和 const,但我认为如果您想了解更多信息,已接受的答案 here 解释得很好。

  • dynamic a;var a; 实际上是一样的:它们都声明了一个动态类型的变量。

  • 检查变量类型的两种方法是using the is operator 和使用.runtimeType,两者的工作方式不同。请参见以下示例:

    dynamic b; // b is now a dynamic type, no value
    print(b is dynamic); // true
    print(b is Null); // true
    print(b is String); // false
    print(b is int); // false
    print(b.runtimeType); // Null
    
    b = "hello"; // dynamic type, String value
    print(b is dynamic); // true
    print(b is Null); // false
    print(b is String); // true
    print(b is int); // false
    print(b.runtimeType); // String
    
    b = 5; // dynamic type, int value
    print(b is dynamic); // true
    print(b is Null); // false
    print(b is String); // false
    print(b is int); // true
    print(b.runtimeType); // int
    

答案 8 :(得分:0)

动态与var 在比较中可以考虑的一个方面是在同时使用带有初始化的var声明时考虑到行为,而无法更改动态类型。

但是,动态vs var并不是我要问的问题。 我想问一下动态与对象之间的区别是什么。

这里是DO annotate with Object instead of dynamic to indicate any object is allowed.

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

答案 9 :(得分:0)

dynamic变量可以更改其类型,而var类型则不能更改。

例如:

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

答案 10 :(得分:0)

dynamic是一种数据类型,指示dart中的所有数据类型

var是一种类似于“ final”的变量声明方式,它采用其值的数据类型

答案 11 :(得分:0)

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

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

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