ChatGPT解决这个技术问题 Extra ChatGPT

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

根据this article

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

那么,dynamicvar 有什么区别?什么时候使用?

我相信,标记为 var 的变量可以初始化为任何类型,但之后只能分配返回该类型的表达式。虽然标记为 dynamic 的变量都可以初始化为任何类型,然后分配给可以更改该类型的表达式。因此,类型在变量初始化后是动态的。

T
Tharindu Lakshan

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

var 是一个关键字,意思是“我不关心这里的类型是什么”。 Dart 会将 var 关键字替换为初始化器类型,如果没有初始化器,则默认保留 dynamic

如果您希望变量赋值在其生命周期内发生变化,请使用 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"];

为什么还要有一个 var 关键字?只需将其设为默认值,就像 python 一样。
↑我认为这让编译器更快。
也许这随着 Dart 2 改变了(我不知道 Dart 1)。这是一个非常古老的答案。在这种情况下,它应该被更新。另请注意,在 Dart 2 中,如果 var 未初始化,它似乎是 dynamic(您可以执行例如 var foo; foo = "str; foo = 1;(或 Object 类型?)这值得澄清。
他甚至没有询问 final 或 const .. 这是可以接受的答案吗???
这个答案不反映问题
M
Mimina

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

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 v 时。没有初始化,var v 与动态 v 相同
case#2 用 var 关键字声明的未初始化变量只能像 var a; 一样改变它的类型,但 var a=123; 不能改变它的类型,它将永远是整数。
r
rough

DartPad 中试试这个:

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

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


仅当您分配给var时。你总是可以这样做: var a;一个=“嗨”; a=123;这是合法的。
@AshwinPrabhu 是的,因为当我们执行 var a; 时,adynamic 的一种类型,这意味着我们可以分配任何类型 intdouble 因为 dynamic 是所有飞镖对象的基础类型
T
Tom Yeh

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

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 编辑器可能会执行额外的类型推断,在这种情况下它会执行,但请记住这是超出规范的行为。
@SethLadd var a = "一些字符串";不会创建具有动态类型的变量,因为赋值运算符,a 将具有固定类型的 String(在本例中)。
@SethLadd 在第二种情况下 var a="abc" a 不是动态类型。它是一个字符串类型的变量。 var a; 在这种特殊情况下,当我们不初始化变量时,a 是一种动态类型。
J
John Wang
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 。


M
Magnus

为了澄清前面的一些答案,当您将变量声明为 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 关键字
M
Milo Legends

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

关键字 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 为您提供 Stringint 或其他任何内容,因此人们甚至可以争辩说,在测试它时,指向 String/int 类型的迹象比 dynamic 多。但当然它仍然是 dynamic,因为您可以为它分配一些其他类型。所以总而言之,它可以同时是 dynamic 和它所拥有的任何类型,具体取决于您如何检查它。
M
MagGGG

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

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

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

一开始很难感觉到它,但是动态的我会与泛型类型参数有关。


c
chethanv77777

在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);
}

J
Jéwôm'

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

例如 :

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

Y
Yosef Hesham

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

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


Y
Yasser Ehab

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

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

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