Dart基础(一)-变量、常量、数据类型

简介:

  Dart是谷歌开发的跨平台的计算机高级语言。Dart是面向对象的、类定义的、单继承的语言。它的语法类似C语言(更加类似于swift或者kotlin),可以转译为JavaScript,支持接口(interfaces)、混入(mixins)、抽象类(abstract classes)、泛型(reified generics)、可选类型(optional typing)和静态推断类型sound type system。

Hello world! :

  main()函数是Dart的入口函数,也是所有Dart语言的开端:

void main() {
  print('Hello, World!');
}

Dart中重要的概念:

1.Dart中一切皆对象:

  在其它面向对象语言中变量类型一般包含基础数据类型和对象类型(或者引用类型),例如swift或者java。在Dart中,声明的每个变量都是一个类的对象;无论是数字(numbers),函数(functions)和null都是对象;并且除了null(如果你启用了sound null safety),所有对象继承自Object类。

2.Dart中是强引用类型的(strong):

  不像swift或者OC中有weak弱引用,Dart中的变量或者属性都是strong强引用的。虽然Dart是强类型的,但类型注释是可选的,因为Dart可以推断类型。在下面的代码中,number被推断为int类型:

  var number = 23;
  print(number.runtimeType);  // 打印int
3.Dart中是空安全的(null safety):

  null safety是在Dart 2.12中引入的。当您选择null safety时,您代码中的类型默认情况下是不可为空的,这意味着值不能为空,除非您说它们可以为空。示例代码如下:

  int? number2; // number2可以为空也可以是int类型的值
  number2 = null;
  number2 = 34;
  int number3;
  number3 = null; // 报错:number3不能为null
4.Dart中可以推断确定变量类型:

  Dart中推断确定变量的类型有两种,一种是在编译时,一种是在运行时。在Dart中,声明变量和属性基本都是编译时已经确定其类型,但是用关键字dynamic修饰的变量和属性是在编译时才能确定的。
  dynamic修饰的变量和属性的值进行任何成员访问,但可能会失败,并在运行时抛出异常。如果您确实想要那种有风险但灵活的动态分派,那么使用dynamic是合适的类型。
  否则,更喜欢使用Object?Object。在访问值之前,依赖于is检查和类型提升,以确保值的运行时类型支持希望访问的成员。

            Object? number;   // 可以为任意类型的值
            dynamic number2;  // 可以为任意类型的值
            number = null;
            number = 12;
            number.toString();
            number = '123'; // 上一行number是int值,可以改变变量的类型
            // print(number + 1);  // 编译时报错,number2是String值
            if (number is int) {  // 判断类型
              print(number + 1);
            }
            print(number.runtimeType);
            number2 = null;
            number2 = 12;
            number2 = '123';
            if (number2 is int) {  // 判断类型
              print(number2 + 1);  // 编译时报错
            }
            print(number2 + 1); // 编译时不报错,运行时报错,number2是String值
5.Dart支持泛型类型:

  Dart支持泛型类型,如List(整数列表)或List(任何类型的对象列表)。

6.Dart支持顶级函数和变量

  Dart支持顶级函数(如main())和变量,以及绑定到类或对象的函数或者变量(分别为静态方法或者静态变量和实例方法或者实例变量)。还可以在函数中创建函数(嵌套函数或局部函数)。实例变量有时被称为字段或属性。

7.Dart没有权限修饰符:

  与Java不同,Dart没有publicprotectedprivate权限修饰符。如果标识符以下划线(_)开头,则它是其库或者类的私有。

8.私有变量、常量、函数都以下划线开头:

  标识符可以以字母或下划线(_)开头,然后是这些字符和数字的任意组合。

class Some {
  // 静态变量,类属性
  static int type = 0;
  // 实例变量,实例属性,实例字段
  late final String name;
  // 私有属性
  late String _privateProperty;
  // 可供外界访问方法
  void show() {
    _show();
  }
  // 静态方法,类方法
  static void showType() {
    print(type);
  }
  // 私有函数
  void _show() {
    print(_privateProperty);
  }
}
9.Dart中的表达式和语句:

  Dart语法中有expressions( 表达式有运行时值)和 statements(语句没有运行时值 )。 例如,条件表达式condition ? expr1 : expr2 的值可能是 expr1 或 expr2 。 将其与 if-else 语句相比较,if-else 语句没有值。 一条语句通常包含一个或多个表达式,相反表达式不能直接包含语句。

            var number = 1;
            final bool isBigger;
            if (number > 10) {
              isBigger = true;
            }
            else {
              isBigger = false;
            }
            var isBigger2 = (number > 10) ? true : false;
10.Dart中警告和错误

  Dart工具可以报告两种问题:warnings(警告)和errors(错误)。警告只是表示您的代码可能无法工作,但它们不会阻止您的程序执行。错误可以是编译时的,也可以是运行时的。编译时错误会阻止代码执行;运行时错误会导致在执行代码时引发异常。

Dart中的关键字

关键字 关键字 关键字 关键字
abstract 2 else import 2 show 1
as 2 enum in static 2
assert export 2 interface 2 super
async 1 extends is switch
await 3 extension 2 late 2 sync 1
break external 2 library 2 this
case factory 2 mixin 2 throw
catch false new true
class final null try
const finally on 1 typedef 2
continue for operator 2 var
covariant 2 Function 2 part 2 void
default get 2 required 2 while
deferred 2 hide 1 rethrow with
do if return yield 3
dynamic 2 implements 2 set 2

  避免使用这些词作为标识。但是,如果有必要,标记有上标的关键字可以是标识符。

标识符命名规则:

  • 变量的名称必须有数字,字母,下划线和美元符($)组成
  • 标识符不能以数字开头
  • 标识符不能是保留字或关键字,见关键字说明
  • 标识符是区分大小写的;例如:nameName不是同一个变量
  • 标识符(变量和函数)一定要通俗名义

变量:

1.变量的定义:

  变量定义有三种常见的方法,一种是var定义,一种是指定具体类型的定义,还有一种是dynamic定义。
  在空安全模式下(null safety),变量在使用之前必须被初始化赋值,除非该变量允许为空(例如int?)。

1.1var定义变量:

  var定义变量,不明确变量的类型,Dart自己会有类型检查,会根据var关键字在定义变量时所赋予的初值的类型明确变量的类型。var定义变量根据赋值的时机分为两种情况:一种是定义时随即赋值;一种是先声明变量,在之后代码中另行赋值。

1.1.1var定义变量随即赋值:

  上述中说到,在赋值时确定了变量类型,在赋值之后,可以赋值其它类型吗?代码如下:

  var number2 = 12; // 等价于 int number2 = 12;
  number2 = 14;
  var result = number2 + 1;  // 正常运行
  // number2 = null;  // 编译报错
  // number2 = '123'; // 编译报错

  如代码所示,这种声明变量并赋值的变量,其后无法进行其它类型的赋值,它与指定具体类型定义变量等价。

1.1.2var定义变量后,另行赋值:

  与1.1.1中问题进行对比:

  var number; // 等价于 Object? number;
  number = 12;
  number = null;  // 不会报错
  number = '123'; // 不会报错
  // var result = number + 1;  // 编译时通过,运行时报错,上一行代码表示,number为String类型
  var result2 = number + '1';  // 正常运行

  如代码所示,这种声明并赋值的变量,其后可以进行其它类型的赋值,并且该变量的类型与最近一次赋值的类型相同;但是之后对其进行已赋值过的类型进行操作,编译时不会报错,运行时会报类型不匹配的错误;该定义变量与指定类型为Object?变量等价。

1.2指定具体类型的定义变量:
  int number = 1;
  String str = '123';
1.3动态变量即dynamic定义的变量:

  dynamic定义的变量,编译时不会进行其类型的确定,而是在运行时确定;并且该变量可以进行任意类型的操作,编译时不报错,只有在运行时才会报错;其运行时的类型与最近一次赋值的类型相同。

  dynamic number = 1;
  var result = number + '1';  // 编译通过,运行时报类型不匹配错误
  number = '123';
  var result2 = number + '4';  // 正常运行

  dynamic一般用于泛型(以后会讲到),且必须对其类型有确切的掌握,不然运行时报错就不可避免了。

2.初始值(Default value):
  • 具有可空类型的未初始化变量的初始值为null
  • 在空安全模式下(null safety),局部变量在使用之前必须被初始化赋值,除非该变量允许为空(例如int?)。
  • 顶级和类变量是延迟初始化的,且使用之前必须被初始化赋值。
  int? number2;
  print(number2);
  int number;
  // print(number);  // 空安全模式下,number没有初始化,且不能为空,所以报错
  number = 2;
  print(number); // 正常运行
class Some {
  // static int type; // 报错
  static int type = 1;
}

常量:

定义:

  不更改的变量或者初始化后无法更改的变量就是常量,在Dart中声明常量用关键字const或者final

constfinal联系:
  • 都是编译时常量;
  • 只能初始化赋值一次,其后无法修改值;
  • 在类中都可以和static一起使用表示类级别的属性。
constfinal区别:
  • const常量声明时可以省略,而final不能省略;
  • 类中声明属性和字段使用final,不用const
  • const常量为编译时常量,声明时必须初始化赋值,而final常量还是运行时常量可以先声明再赋值(即常说的懒加载),但是final常量必须在使用前进行初始化赋值;
  • const修饰对象时,对象的属性无法修改,而final修饰对象,对象属性可以修改。

内置类型:

Dart支持的类型:
  • Numbers (数值类型int, double)
  • Strings (字符串String)
  • Booleans (bool)
  • Lists (List,常见的数组)
  • Sets (集合Set)
  • Maps (哈希表或者字典Map)
  • Runes (Runes;通常被“characters”API所取代)
  • Symbols (符号Symbol)
  • 空值 null (空类Null)
Dart特殊的类型:
  • Object:除Null外的所有Dart类的超类;
  • FutureStream:用于异步支持;
  • Iterable:用于for-in循环和同步生成器函数;
  • Never:表示一个表达式永远不能成功完成求值,通常用于总是抛出异常的函数;
  • dynamic:表示要禁用静态检查,通常你应该使用Object?代替;
  • void:表示该值从未被使用。通常用作返回类型。
Numbers类型:

  整形数值类型(int);其取值范围,不大于64位的整数值,取决于平台;在本地平台上,值可以从-263到263 - 1。在web上,整数值表示为JavaScript数字(64位浮点值,没有小数部分),取值范围从-253到253 - 1。
  double类型:64位(双精度)浮点数,由IEEE 754标准指定。
  intdouble都是 num的子类。num类型包括基本操作符,如+、-、/和*,在这里您还可以找到abs()ceil()floor()等方法。(位操作符,如>>,定义在int类中。)如果num及其子类型没有您要寻找的内容,那么dart:math库可能有。

            var x = 1;
            var hex = 0xDEADBEEF;
            var exponent = 8e5;
            var y = 1.1;
            var exponents = 1.42e5;
            num n = 1; // x可以是int或者double
            n += 2.5;
            assert((3 << 1) == 6); // 0011 << 1 == 0110
            assert((3 | 4) == 7); // 0011 | 0100 == 0111
            assert((3 & 4) == 0); // 0011 & 0100 == 0000
Strings类型:
  • String类型包含一个UTF-16代码单元序列;
  • 可以用''或者""初始化赋值;
  • 可以用r初始化赋值;
  • 可以用‘’‘’‘’或者""""""初始化多行字符串;
  • 可以用+拼接字符串;
  • 可以用==判断字符串内容相同。
            String s1 = '123';
            String s2 = "123";
            String s3 = r"123";
            String s4 = '''123
            456
            789
            ''';
            String s5 = """123
            456
            789
            """;
            var s6 = "I am " + "Lucy!";
            print("object" == "object");  // true
Booleans类型:
  • bool类型,两个值truefalse;它们都是编译时常量;
  • 条件判断没有隐式类型转换。
            var number = 123;
            var str = '123';
            if (number == str) {
              print("隐式转换");
            }
            else {
              print("没有转换");  // 没有转换
            }
Lists类型:
  • List中元素可以重复;
  • 支持iffor......?等语法;
      List数组类型,常见初始化和操作代码如下:
            var intList = [1, 2, 3];
            List intList3 = [];
            var list2 = [0, ...intList];
            var strList = ['Car', 'Boat','Plane',];
            List strList2 = [];
            var hasZheng = true;
            var strList3 = [
              '周',
              '吴',
              if (hasZheng) '郑',
            ];
            var listOfInts = [1, 2, 3];
            var listOfStrings = [
              '#0',
              for (var i in listOfInts) '#$i'
            ];
            print(listOfStrings);
Sets类型:
  • Set中元素唯一;
  • 支持iffor......?等语法;
      Set集合类型,常见初始化和操作代码如下:
            var intSets = {1, 1, 1};
            var intSets2 = {};
            intSets2.add(2);
            intSets2.addAll(intSets);
            print(intSets); // {1}
            print(intSets2);  // {2, 1}
            var hasZheng = true;
            Set strSets = {'周', '吴', if (hasZheng) '郑'};
            Set strSets2 = {...strSets, '王'};
            print(strSets2);  // {周, 吴, 郑, 王}
Maps类型:
  • Map是一个关联键(key)和值(value)的对象的集合;
  • 键和值都可以是任何类型的对象;
  • 每个键只出现一次,但您可以多次使用相同的值;
  • 支持iffor......?等语法;
      Set集合类型,常见初始化和操作代码如下:
            var nameMap = {"first" : "周", "second" : "吴"};
            nameMap['third'] = "郑";
            Map someMap = {1 : "周", 2 : "吴"};
            var someMap2 = {1 : "周", 2 : "吴", ...someMap};
            print(nameMap); // {first: 周, second: 吴, third: 郑}
            print(someMap2);  // {1: 周, 2: 吴}

其它:

Dart之旅

你可能感兴趣的:(Dart基础(一)-变量、常量、数据类型)