根据this article:
您可能知道,动态(现在称为)是未提供静态类型注释时的替代类型。
那么,dynamic
和 var
有什么区别?什么时候使用?
var
的变量可以初始化为任何类型,但之后只能分配返回该类型的表达式。虽然标记为 dynamic
的变量都可以初始化为任何类型,然后分配给可以更改该类型的表达式。因此,类型在变量初始化后是动态的。
dynamic
是所有 Dart 对象的基础类型。在大多数情况下,您不需要显式使用它。
var
是一个关键字,意思是“我不关心这里的类型是什么”。 Dart 会将 var
关键字替换为初始化器类型,如果没有初始化器,则默认保留 dynamic
。
如果您希望变量赋值在其生命周期内发生变化,请使用 var
:
var msg = "Hello world.";
msg = "Hello world again.";
如果您希望变量赋值在其生命周期内保持不变,请使用 final
:
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"];
动态:可以改变变量的类型,&可以在后面的代码中改变变量的值。
var:不能改变变量的类型,但可以在后面的代码中改变变量的值。
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.
var
关键字声明的未初始化变量只能像 var a;
一样改变它的类型,但 var a=123;
不能改变它的类型,它将永远是整数。
在 DartPad 中试试这个:
void main() {
dynamic x = 'hal';
x = 123;
print(x);
var a = 'hal';
a = 123;
print(a);
}
您可以更改 x 的类型,但不能更改 a。
var a;
时,a
是 dynamic
的一种类型,这意味着我们可以分配任何类型 int
或 double
因为 dynamic
是所有飞镖对象的基础类型
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
是一种特殊类型,表明它可以是任何类型(也称为类)。例如,通过将对象强制转换为 dynamic
,您可以调用任何方法(假设有一个)。
(foo as dynamic).whatever(); //valid. compiler won't check if whatever() exists
(foo as var).whatever(); //illegal. var is not a type
var a
创建一个动态类型的变量。 String a
创建一个字符串类型的变量。 Dart 编辑器可能会执行额外的类型推断,在这种情况下它会执行,但请记住这是超出规范的行为。
var a="abc"
a
不是动态类型。它是一个字符串类型的变量。 var a;
在这种特殊情况下,当我们不初始化变量时,a
是一种动态类型。
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 。
为了澄清前面的一些答案,当您将变量声明为 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
。
var a;
赋值,那么该变量将自动属于 dynamic
我们不必显式使用 dynamic
关键字
查看以前的答案,我希望这可以澄清/总结一切:
有关键字 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,但如果你想了解更多,我认为这里接受的答案很好地解释了它。
动态的;和 var a;实际上是相同的:它们都声明了一个动态类型的变量。
检查变量类型的两种方法是使用 is 运算符和使用不同工作方式的 .runtimeType。看下面的例子:动态b; // b 现在是动态类型,没有值 print(b 是动态的); // true print(b is Null); // true print(b 是字符串); // false print(b is int); // false print(b.runtimeType); // 空 b = "你好"; // 动态类型,字符串值 print(b 是动态的); // true print(b is Null); // false print(b 是字符串); // true print(b is int); // false print(b.runtimeType); // 字符串 b = 5; // 动态类型,int 值 print(b 是动态的); // true print(b is Null); // false print(b 是字符串); // false print(b is int); // true print(b.runtimeType); // 整数
dynamic
变量的类型是 dynamic
。正如您在最后一段代码中显示的那样,在检查类型时,它既是 dynamic
,也是最后分配给它的任何类型。并且由于 runtimeType
为您提供 String
、int
或其他任何内容,因此人们甚至可以争辩说,在测试它时,指向 String
/int
类型的迹象比 dynamic
多。但当然它仍然是 dynamic
,因为您可以为它分配一些其他类型。所以总而言之,它可以同时是 dynamic
和它所拥有的任何类型,具体取决于您如何检查它。
在比较动态与 var 时可以考虑的方面之一是考虑使用 var 声明和初始化时的行为,同时在动态的情况下不可能更改类型。
但是动态 vs var 不是我要问的问题。我会问更多动态与对象之间的区别。
这是一个DO annotate with Object instead of dynamic to indicate any object is allowed.
一开始很难感觉到它,但是动态的我会与泛型类型参数有关。
在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);
}
dynamic
变量可以更改其类型,而 var
类型不能更改。
例如 :
var myVar = 'hello';
dynamic myDynamicVar = 'hello';
myVar = 123; // not possible
myDynamicVar = 123; // possible
dynamic 是一种数据类型,表示 dart 中的所有数据类型
var 是一种类似于“final”的变量声明方式,它采用其值的数据类型
如果使用 var,则无法更改变量的数据类型。但是如果你使用动态,你可以自由地改变它。例如。
dynamic x = 12; // type: integer
x= "Hello world"; // type: string
如果您使用 var 而不是 dynamic 执行相同操作,这将毫无问题,您将收到错误,因为您无法更改数据类型,因为它在初始化时自动分配给变量。
不定期副业成功案例分享
var
未初始化,它似乎是dynamic
(您可以执行例如var foo; foo = "str; foo = 1;
(或 Object 类型?)这值得澄清。