Dart中"var"和"dynamic"类型的区别?

Ger*_*ero 39 dart

根据这篇文章:

您可能知道,dynamic(因为它现在被称为)是未提供静态类型注释时的替身类型.

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

Mim*_*ina 45

动态:可以改变变量的类型,&可以在代码后面改变变量的值。

var: 不能改变变量的TYPE,但可以在代码后面改变变量的VALUE。

final: 不能改变变量的类型,&不能在代码后面改变变量的值。

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.
Run Code Online (Sandbox Code Playgroud)

  • 仅当您初始化 var v 时。如果没有初始化,var v 与动态 v 相同 (9认同)

Joh*_*ans 42

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

var是一个关键字,意思是"我不关心这里的类型是什么.",默认情况下保持动态.

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

var msg = "Hello world.";
msg = "Hello world again.";
Run Code Online (Sandbox Code Playgroud)

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

final msg = "Hello world.";
Run Code Online (Sandbox Code Playgroud)

使用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"];
Run Code Online (Sandbox Code Playgroud)

  • 也许这在 Dart 2 中发生了变化(我不知道 Dart 1)。这是一个非常古老的答案。在这种情况下,它应该被更新。另请注意,在 Dart 2 中,如果 `var` 未初始化,则它看起来是 `dynamic`(您可以执行例如 `var foo; foo = "str; foo = 1;`(或 Object 类型?)这值得澄清。 (5认同)
  • ↑这让编译器更快,我想。 (3认同)
  • 这个答案没有反映问题 (3认同)
  • 他甚至没有问final或const..这怎么是可接受的答案??? (2认同)

rou*_*ugh 19

DartPad中尝试一下

void main() {
  dynamic x = 'hal';
  x = 123;
  print(x);
  var a = 'hal';
  a = 123;
  print(a);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 仅当您分配给 var 时。你总是可以这样做:var a; 一个=“嗨”;a=123;这是合法的。 (10认同)
  • @AshwinPrabhu是的,因为当我们执行“var a;”时,“a”是“dynamic”的一种类型,这意味着我们可以分配任何类型“int”或“double”,因为“dynamic”是所有 dart 对象的底层类型 (3认同)

Joh*_*ang 12

var a ;
a = 123;
print(a is int);
print(a);
a = 'hal';
print(a is String);
Run Code Online (Sandbox Code Playgroud)

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

var b = 321;
print(b is int);
print(b);
//b = 'hal'; //error
print(b is String);
Run Code Online (Sandbox Code Playgroud)

当使用初始值定义时,在这种情况下 var 是 int。


Tom*_*Yeh 10

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
Run Code Online (Sandbox Code Playgroud)

另一方面,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
Run Code Online (Sandbox Code Playgroud)

  • 从技术上讲,第一个示例显示了两个不相等的语句.`var a`创建一个Dynamic类型的变量.`String a`创建一个String类型的变量.Dart编辑器可以执行其他类型推断,在这种情况下它可以执行,但请记住这是超出规范的行为. (3认同)
  • @SethLadd var a = "一些字符串"; 不会创建动态类型的变量,因为赋值运算符,a 将具有固定的 String 类型(在本例中)。 (2认同)

小智 8

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

关键字var、final 和 const。这些是声明一个变量(以表明它的存在)(旁注:声明与初始化

然后还有String、int、List、dynamic等类型。(类型表示变量应该保存什么样的值,这是为了类型安全

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

String a; // a is now a String type
int b; // b is now an int type
Run Code Online (Sandbox Code Playgroud)

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

var a = "hello"; // a is now a String type
var b = 5; // b is now an int type
Run Code Online (Sandbox Code Playgroud)

现在,当您尝试使用 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
Run Code Online (Sandbox Code Playgroud)

因此,为了解决最初对文章引用的困惑,

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

它只是意味着,如果您没有显式声明其类型(您使用 var 声明变量)并且在没有初始化的情况下这样做,它只是将其类型推断为动态:

var b; // b is now a dynamic type, the following will not have any errors.
b = "hello";
b = 5; 
b = true;
Run Code Online (Sandbox Code Playgroud)

其他注意事项:

  • 不知道为什么人们开始谈论 Final 和 const,但我认为如果您想了解更多信息,这里接受的答案很好地解释了这一点。

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

  • 检查变量类型的两种方法是使用 is 运算符和使用.runtimeTypewhich 的工作方式不同。请参见以下示例:

    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
    
    Run Code Online (Sandbox Code Playgroud)


Mag*_*s W 5

为了澄清之前的一些答案,当您将变量声明为 时dynamic,它的类型会根据您分配给它的内容而变化。当你声明 a 时var,类型一旦被赋值就被设置了,之后就不能再改变了。

例如,以下代码:

dynamic foo = 'foo';
print('foo is ${foo.runtimeType} ($foo)');
foo = 123;
print('foo is ${foo.runtimeType} ($foo)');
Run Code Online (Sandbox Code Playgroud)

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

foo is String (foo)
foo is int (123)
Run Code Online (Sandbox Code Playgroud)

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

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)');
Run Code Online (Sandbox Code Playgroud)

长话短说 -dynamic如果你想要一个非类型化变量,请使用,var当你想要一个类型化变量时使用你分配给它的任何类型。