Dartb变量声明

1.本篇简介

这一篇我们主要介绍Dart中变量声明的关键字,总共有以下几个关键字:var,final,const,Object,dynamic。下面我们会通过示例来介绍每个关键字的使用和特点。

2.var

2.1 示例

我们先通过以下代码,来看看var是怎么使用的:

    ```

    var a =1;// ==> 等价与 int a = 1;

    print(a);//1

    print(a is int);//true is 关键字用来判断 变量是否某类型,此段代码中 判断a是否为int类型

    var b = "ss";

    print(b);//ss

    print(b is int);//false

    ```

上面代码可以看出,var能用于声明任何一种的变量类型,但是,根据后面print函数打印的结果(is关键字处),dart 好像能推断出变量的实际类型,我们接着往下看。

    ```

    var a = 1;

    a = "ss";//报错:A value of type 'String' can't be assigned to a variable of type 'int'.

    //类型'String'的值不能赋给类型'int'的变量

    ```

明显,dart给我们报错了,String类型的值不能赋给int类型的变量(在写出代码时,as 已经标红)。

上面的代码等价于java中:

    ``

    int a = 1;

    a = "ss";

    ``` 

这样操作变量,明显是错的,dart本身也是一个强类型语言,var只是dart提供的一个语法糖,当var变量在进行编译的时候,会自动匹配到对应的实际类型,并用实际类型来替换该类型的声明。

2.2 总结

通过上面的示例,我们可以总结出var使用方法与需要注意的地方。

1.var 可以接受任何变量类型。

2.var声明的变量一旦赋值,类型确定,不能再改变量类型。

3.final 和 const

3.1示例

这里我们将 final 和 const 放在一起进行说明,因为这两个关键字有一定的异同点,首先我们通过代码来了解final和const的相同点。

```dart

final a;//错误 The final variable ';' must be initialized. 必须初始化final变量

const b;// 错误 同上

final a1 ="ss";// ==>等价于 final String a1 = "ss";

const b1 ="ss"; // ==> 等价于 const String b1 = "ss";

a1 = "sss";//错误  a final variable ,can only be set once; final变量只能设置一次

b1 = "sss";//错误 同上

final String a2 ="ss"; // ==> 等价于 final a2 = "ss"

const String b2 ="ss"; // ==> 等价于 const b2 = "ss";

final var a3 ="ss";//错误 Members can't be declared to be both 'final' and 'var'.Try removing the keyword 'var'.

  //成员不能同时被声明为“final”和“var”。尝试删除关键字“var”。

const var b3 ="ss";//错误  同上

```

通过上面的示例可以看出,final和const的相同点有:

1.final 和 const 声明变量的时候必须初始化,而且初始化后不允许修改。

2.使用final或const修饰变量时,可以省略变量具体类型如:上面的String。

3.final或const 不能与var同用。

我们再次通过代码,来看看final和const的不同点:

```dart

 // 示例1

  final finalTime =DateTime.now();//获取当前时间

  const constTime =DateTime.now();//Cannot invoke a non-'const' constructor where a const expression is expected. 不能在需要const表达式的地方调用非'const'构造函数。

//      示例2

  final finalList = [1,2,3];

  finalList[0] =3;

  print(finalList);//3,2,3

  const constList = [1,2,3];

  constList[0] =3;

  print(constList);//Cannot modify an unmodifiable list 无法修改无法修改的列表

//      示例3

  final finalList1 = [1,2,3];

  final finalList2 = [1,2,3];

  const constList1 = [1,2,3];

  const constList2 = [1,2,3];

  print(identical(finalList1, finalList2));//false  identical 用于判断两个变量是否指向同一个对象

  print(identical(constList1, constList2));//true

```      

上面代码中,分成了三个示例,每一个示例,表达了final和const的一个不同点。我们对三个示例进行分析:

  1. DateTime.now()用于获取当前的时间,是DateTime的一个命名函数,final修饰的时候并没有什么问题,但是用const进行修饰的时候,报错。不能在const表达式的地方调用非“const”构造函数。我们先看final和const的定义:

    final用于修饰在运行时有确定值的常量(运行时常量,在代码运行的时候才会被赋值,且final是惰性初始化,在运行时第一次使用前才会被初始化)

    const用于修饰在编译时有确定值的常量。(编译时常量就是在代码编译的时候,这个常量就被存入到引用它的类的常量池中了,与定义它的类没有什么关系,运行时引用编译时常量,并不会使定义这个常量的类被加载)

    那么上面的示例1中,DateTime.now()是获取当前时间的,获取当前时间必须程序运行起来才能获取到值,那么在编译期间是不能确定值的。修改构造函数的为const的前提条件是该类中的所有成员变量都要被final或const修饰。

    2.示例2定义了两个list,分别用final和const来修饰,可以看到,final修饰的list允许修改其内部的值,const修饰的list不允许修改其内部的值。表明:const的不可变性具有传递性,final的不可变性不具有传递性。

    3.示例3定义了四个list,其中两个用final修饰,两个用const修饰,identical方法用于判断两个变量是否指向对象,可以看到final修饰的两个相同的list并不指向同一个对象,const修饰的两个相同的list则指向同一个对象。表明:值相同时final在内存中会重复创建,const会引用相同的值。

以上三点就是final和const的不同点。

4.Object和dynamic

这里我们同样将Object和dynamic放在一起进行说明,因为这两个也是有一定的异同点。下面我们通过代码来展示相同点。

```dart

Object o =3;

o ="object";

print(o);//object

dynamic d =3;

d ="dynamic";

print(dynamic);//dynamic

```

上面代码中,和var截然不同的是,原本是int类型的 变量o 和 变量d,在后面都被重新赋值为String类型,并且能够输出变量而不报错,表示 Object和dynamic 能接受任意类型,并且是动态的(动态任意类型)。

我们再看下面的代码:

```dart

class Person{

    void speak(){

        print("hello world");    

      }

    @override

     void toString(){

        print("Person");    

      }

    }

    Object o = Person();

    o.toString();//Person

    o.speak();//The method 'speak' isn't defined for the class 'Object' ; speak方法没有为Object类定义

    dynamic d = Person();

    d.toString();//Person

    d.speak();//hello world

```

上面代码中,定义了一个Person类,重写了toString并定义了一个speak方法,可以看到,当变量o调用toString方法时能正常打印,但当变量o调用Person中定义的speak方法时,报错,speak方法没有为Object类定义,也就是说dart认为变量o的类型为Object。而用dynamic声明的变量d 并没有报错。让我们来看看下面的代码,看看dynamic声明的变量在什么时候会报错:

```dart

    //在上面的基础上 我们再定义一个类

    class Machine{

        void work(){

            print("hong long long");

          }

    }

    dynamic d = Person();

    d.toString();//Person

    d.speak();//hello world

    d.work();//Class 'Person' has no instance method 'work'. 类“Person”没有实例方法“work”。

```

可以看到,当我们调用Machine类中定义的work方法时,变量d 报错了,那么此时变量d的类型就是Person。

由上面的结果可以总结出Object和dynamic的不同点:

1.检查类型的时间:
1.1 Object在编译阶段检查类型。
1.2 dynamic在运行时检查类型。

2.实例类型:
2.1 Object声明的变量,最后的类型为Object(Object为所有类的基类,多态,导致Object能够用来创建不同实例的变量),所以,Object声明的变量,只能调用在Object中定义过的方法(函数)

2.2*** dynamic声明的变量,因为在运行时才会进行类型检查,所以只有在运行时才会成为对应的实例,(编译阶段不检查类型,所以出现了上述中 变量d 调用Machine类中的work方法并报错),和Object不同能调用Person方法的原因是:被dynamic修饰的变量编译器会提供尽可能多的组合,使得dynamic声明的变量能够调用尽可能多的方法(函数)***。

5.最后

在实际开发时,尽量少用dynamic,因为它容易引起运行时错误。

const 与 static 连用为静态常量。

类中的变量如果被const修饰,外界引用时,并不会导致这个类被加载,读者可以自己写一个类,并在类中定义一个静态代码块进行检测。

最后附上思维导图一张:

image

作者本人也是刚接触dart 和 flutter,写博客的原因是因为想记录学习的脚步,同时也是为了自己更加深刻的理解。如果有不对的地方,请务必指正。也欢迎大家一起学习交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容