第一节: Dart语法了解,认识变量,常量,数据类型

Dart 语法学习目录

第一节: Dart 语法了解,认识变量,常量,数据类型
第二节: Dart 操作符(运算符)
第三节: Dart 中流程控制,条件判断以及循环语句
第四节: Dart 中常用集合 List/Map
第五节: Dart 函数使用,声明函数/匿名函数/可选参数/作用域/闭包
第六节: Dart 面向对象/构造函数/静态属性
第七节: Dart中抽象类abstract/接口implements/混入Mixin
第八节: Dart中泛型/泛型定义与使用
第九节: Dart 中的库/自定义库/内置库/第三方库


1. dart的基本用法了解

1.1 dart入口函数与输出

dart运行需要一个入口函数为main,

通过下面的示例,先简单了解dart基本使用

在dart语法中输出控制台为print() 方法

// 有返回值的dart
main(){
    // 打印
    print("hello dart")
}

结果会在控制台输出hello dart

我们也可以将main 入口函数定义为没有返回值的函数,

// 没有返回指定入口
void main(){
    print("你好 dart")
}

void 是限定函数的返回来写为空


1.2 dart语言中的注释
//   单行注释
///  单行注释
/* 
    多行注释 
*/


2. Dart 语言重要概念的理解

  1. 任何保存在变量中的都是一个 对象 , 并且所有的对象都是对应一个 的实例。 无论是数字,函数和 null 都是对象。所有对象继承自 Object类。
  2. 尽管 Dart 是强类型的,但是 Dart 可以推断类型,所以类型注释是可选的。
  3. Dart 支持泛型,如 List <int> (整数列表)或 List <dynamic> (任何类型的对象列表)
  4. Dart 支持顶级函数(例如 main() ), 同样函数绑定在类或对象上(分别是 静态函数实例函数 )。 以及支持函数内创建函数 ( 嵌套局部函数 ) 。
  5. Dart 支持顶级 变量 , 同样变量绑定在类或对象上(静态变量和实例变量)。 实例变量有时称为字段或属性。
  6. 与 Java 不同,Dart 没有关键字 “public” , “protected” 和 “private” 。 如果标识符以下划线(_)开头,则它相对于库是私有的。
  7. 标识符 以字母或下划线(_)开头,后跟任意字母和数字组合。
  8. Dart 语法中包含 表达式( expressions )(有运行时值)和 语句( statements )(没有运行时值)。 例如,条件表达式condition ? expr1 : expr2 的值可能是 expr1expr2 。 将其与 if-else 语句相比较,if-else 语句没有值。 一条语句通常包含一个或多个表达式,相反表达式不能直接包含语句。
  9. Dart 工具提示两种类型问题:警告错误。 警告只是表明代码可能无法正常工作,但不会阻止程序的执行。 错误可能是编译时错误或者运行时错误。 编译时错误会阻止代码的执行; 运行时错误会导致代码在执行过程中引发 [异常]

这些重要的概念先有第一定的了解,读一读, 不理解什么意思没有关系,继续往后学,等学完dart以后在会来来理解这些概念


3. Dart语言中的关键字

关键字先看一眼,混个眼熟, 不用刻意的去背,随着学习的深入,大部分关键词都会接触到,或者在自己的代码示例中出现,用多了就熟了

关键字就不在这里罗列了, 了解请移步官网关键字


4. dart中的变量

4.1 dart 标识符命名规则
  1. 变量的名称必须有数字,字母,下划线和美元符($)组成
  2. 标识符不能以数字开头
  3. 标识符不能是保留字或关键字
  4. 变量的名称是区分大小写的, 如果,age和 Age不是同一个变量
  5. 标识符(变量)一定要见名知意,


4.2 变量定义
  1. 使用var 声明变量,此时没有明确类型,编译的时候根据值明确类型

  2. dart变量定义时可以明确类型,来帮助 Dart 去捕获异常以及 让代码运行的更高效

  3. 变量定义为初始化赋值,变量默认值为null

  4. 如果对象不限于单一类型(没有明确的类型),请使用Object或dynamic关键字

根据上面变量定义的描述,我们来好好通过示例来看看变量定义的描述


4.2.1 不明确类型的定义变量

是有var定义变量,不明确变量的类型,dart自己会有类型检查, 会根据var关键字在定义变量时所赋予的初值的类型明确变量的类型

void main(){
    // 定义变量
    // var 定义变量, 值是什么类型,变量就是什么类型
    var str = "hello wrod";
    var num = 1234;

    // 打印变量
    print(str);
    print(num);

    // 判断str num 变量的类型
    print(str is String); // true
    print(num is int);   // true

}

通过示例的打印结果,我们知道了strnum两个变量的数据类型



所以var 定义变量的类型是根据第一次赋值变量的时候推到出来的类型, 也就是说在赋予初始值的时候,变量的类型就已经确定了,

那么问题来了,类型确定了之后的变量还能赋予其他类型的值吗?

看示例:

void main(){
    var str2 = '';
    strs = 123;
    print(str2);
}

// 这样写就会报错, str2 是字符串类型, 赋值数字报错

我们发现一旦变量类型确定在赋值其他类型的变量就会报错.



但是如果通过var 定义变量 并没有赋初值, 那么这个变量不就没办法确定类型

那么此时的类型应该还是默认的类型Null,这样的话,我们是否可以自由给变量赋予任何数据类型的值呢

所有后面可以自由赋值任何数据类型的值,并且可以更改, 当然不建议这么使用

void main(){
    var num;
    // var 定义变量没有赋予初始值, 类型为Null
    print(num is Null); // true
    
    
    num = 123; 
    print(num);     // 123
    
    // 当重新给变量赋值时,类型也会发生变化
    print(num is int);   // true
    print(num is Null);  // false 
    
    
    num = "str";
    print(num);    // 'str'

    // 还可以自由赋予不同数据类型的值
    print(num is String);  // true
    print(num is Null);  // false
}

示例中的代码不会报错, 可以正常输出结果.这样我们就了解了

Dart中,如果使用var关键词定义变量但是没有赋予初始,就好像dart没法限定变量为某一种类型,此时就会像JavaScript变量一样, 可以赋予任何数据类型的值, 而此时变量的类型将有赋予的值的类型来决定

注意:

使用var定义变量但未赋予初始值. 那么变量的值为null,类型为Null

void main(){
    var num;  
    print(num == null);  // true
    print(num is Null);  // true
}

总结:


4.2.2 通过指定类型定义变量

当然了dart也可以在定义变量时限定变量的类型,变量的类型一但被限定, 将不能给变量赋予不同类型的值

示例:

void main(){
  // 定义变量
  // 确定str的类型是字符串类型的变量, str只能赋值字符串,如果赋值其他类型值将会报错
  String str = "hello wrod";
  
  // 限定变量num是数字类型
  int num = 1234;


  // 打印变量
  print(str);
  print(num);
}

注意, var 定义变量时,var 后面就不要在写类型了, 限定了变量类型就不要在使用var了

现在我们对于数据类型还不是特别了解,先认识一下示例中所有的数据类型,后面会详细探讨.


4.3 动态类型dynamic

没有指定类型的变量的类型为 dynamic

void main(){
    dynamic num = 123;
    print(num);

    num = '456';
    print(num);

    print(num is dynamic);    // true
    print(num is String);     // true
}

此时并未指定num变量的类型,类型是有值推导出来的, 所以我们在判断num类型的时候,dynamicString都为true

dynamic 一般在使用泛型时使用

示例:

void main(){
    var list = new List<dynamic>();  //泛型,会在后面总结
    list.add("hello");
    list.add(123);
    print(list);  // [hello, 123]
}

此时表示集合list里可以放任意数据类型的值

泛型是什么?先不用在意,我们会进行总结


5. Dart 中定义常量

5.1 常量定义的基本用法

dart中使用final 和const 关键字定义常量

对于Dart定义常量的了解

  1. finalconst 修饰的变量只能赋值一次,不可更改变量值(定义常量)
  2. 一个 final 变量只能被初始化一次; const变量是一个编译时常量,(Const变量是隐式的final),如果 const 常量在类中,请定义为 static const。
  3. 被final或者const修饰的变量,变量类型可以省略,建议指定数据类型。
  4. 使用关键字定义常量时必须在第一次声明的时候就需要初始化,否则会提示错误:


5.1.1 定义常量

常量就是定义之后,不能再修改值的变量.

void main(){
    // 定义常量
    // const 定义常量
    const str = "不可修改的值";
    print(str);   // 不可修改的值

    // final 定义常量
    final num = 123;
    print(num); //123

}

示例中,可以正常打印出数值, 但是这些常量已经固定, 如果改变这些常量的值,就会报错

如下错误的写法

void main(){
  // 定义常量
  const str = "不可修改的值";

  print(str);

  str = '错误的';  // 会报错,常量不可修改
  print(str);
  
}

通过示例,我们发现常量就算你修改为一样类型的数值也会报错


5.1.2 指定常量类

finalconst 定义常量,其实就是定义变量,这两个关键字在修饰变量是,不允许变量被重新赋值而已, 这两个关键字在修饰常量时,可以省略数据类型,

如果在finalconst修饰常量时没有指定类型,那么变量的类型将有初始赋值的类型决定.

示例:

定义常量时不限定类型

void main(){
    // 定义常量
    // const 定义常量
    const str = "不可修改的值";
    print(str);          // 不可修改的值
    print(str is String);  // true

    // final 定义常量
    final  num = 123;
    print(num);         //123
    print(num is int);   // true

}

通过示例,发现定义的常量类型就是赋值的数据类型

定义变量时限定类型

void main(){
    // 定义常量 限定类型
    // 在修饰常量的关键字和变量之前添加修饰变量的类型

    // const 定义常量
    const String str = "不可修改的值";
    print(str);          // 不可修改的值
    print(str is String);  // true

    // final 定义常量
    final int num = 123;
    print(num);         //123
    print(num is int);   // true

}

我们发现提前修饰变量的类型也没有任何问题

如果你修改时的变量类型和赋值的类型不一致就会报错

void main(){
    // 定义常量 限定类型
    // 在修饰变量的类型和赋值的类型不一致

    // const 定义常量
    const int str = "不可修改的值";
    print(str);          
    print(str is String); 

}

此时不会打印任何内容,会直接报错,因为修饰str变量的类型是int,可是赋予的值的类型是String,所以会直接报错


5.1.3 声明常量初始化赋值,

声明常量时必须在初始化赋值, 否则就会报错

void main(){
    // 定义常量 声明时必须初始化赋值

    // const 定义常量
    //   const str ;
    //   str = "不可修改的值"


    final num;
    num = 20;
}

无论final还是const在声明时未初始化赋值都会报错;


5.2 const 和final 定义常量的区别
5.2.1 常量固定下来的时间不同

Const 变量在编译时就已经固定,最高级 final 变量或类变量在第一次使用时被初始化。

final不仅有const 的编译时常量的特性,最重要的是他运行时常量, final是惰性初始化, 即在运行时第一次使用前才初始化;

void main(){
    // 因为 const 声明常量时 在定义时就初始化,所以这么写是错误的
    // 所以在const 声明变量在编译时就已经固定了,所以此时赋予的是不能是表达式,而应该是一个确定的值. 
    // 所以如下写法是会报错了\

    //   写法一: 实例化
    //   const aa = new DateTime.now();  

    //   写法二:计算
    //   var num = 10;
    //   const aa = 123 * num;

    //   print(aa);


    // final 是在第一次使用前才初始化
    // 所以在声明常量赋值是并没有固定下来,因此初始赋值可以为表达式
    // 下面两种写法完全没问题

    //   写法一: 实例化
    //   final aa = new DateTime.now();


    //   写法二: 计算
    var num = 10;
    final aa = 123 * num;

    print(aa);


}


5.2.2 修饰类的实例

注意修饰类实例的变量可以是final类型 ,但不能是const类型

class Person{
    // 类属性
    String name = '你好';

    // 类方法
    getInfo(){
        print(name);
    }
}


void main(){
    // 类实例化
    // final 修饰类实例化变量
    final person = new Person();
    person.getInfo();   // 你好

    // const就是就会报错
    // const person = new Person();   // 报错
}

因为const是在声明时固定的,所以不能用来修饰类实例化的常量


5.2.3 修饰变量值

任何一个变量都可以拥有一个常量的值

const关键字不只是声明常数变量,您也可以使用它来创建常量值,以及声明创建常量值的构造函数,任何变量都可以有一个常量值。

例如:

void main(){
  var foo = [1,2,3];
  foo.add(6);
  print(foo);  // [1, 2, 3, 6]
}

这样改变值 没有任何关系

但是如果把值限定为常量就会报错

void main(){
    var foo = const [1,2,3];
    foo.add(6);
    print(foo);  // Cannot add to an unmodifiable list
}

因为此时被const修饰的集合[1,2,3]是常量值,不能修改.

但是要注意的是尽管你是用了const限定了常量值,让集合不能添加内容,但是foo确实变量,所以可以直接替换为非常量值

void main(){
    var foo = const [1,2,3];
    
    // 将变量修改为非const值
    foo = [4,5,6];
    // 此时就可以修改二两
    foo.add(7);
    print(foo);  // [4, 5, 6, 7]


}

final关键值不能修饰常量值,

如果使用final修饰常量值就会报错

void main(){
    var foo = final [1,2,3];  // 直接过错
}
  


6. dart的数据类型

6.1 类型的了解

常用的数据类型

  1. Numbers( 数值)

    int

    double

  2. Strings (字符串)

    String

  3. Booleans (布尔)

    bool

  4. List (集合,也被称为数组)

    在Dart中,数组是列表对象, 所以大多数人只是称他们为列表

  5. Map(字典)

    通常来说 Map 是一个键值对相对的对象, 键和值可以是任何类型的对象,每个键

不常用的类型

  1. Set
  2. Rune
  3. Symbol

不常用的方法在这里就不罗列了, 之后有用到咱们在说.

这些类型都可以被初始化为字面量,因为在 Dart 所有的变量终究是一个对象(一个类的实例), 所以变量可以使用 构造涵数 进行初始化。一些内建类型拥有自己的构造函数。

实例:

void main(){
    String str = "字符串";
    print(str);  // 字符串
}


6.2 数值类型

Dart 语言的 Number 有两种类型:

一种是int ,一种是double

  1. int:其取值通常位于 -253和 253-1 之间
  2. double:64-bit (双精度) 浮点数,符合 IEEE 754 标准。

intdouble 都是 num的亚类型。

void main(){

  // 定义数值类型
  //  整数类型不包含小数点
  int num1 = 23;  // init 只能是整型,如果赋值浮点型就报错

  double num2 = 22.5; // double可以是整型也可以是浮点型
  num2 = 21;

  print(num1);
  print(num2);
}


6.3 字符串类型

字符串的创建

  1. 使用单引号'',双引号""
  2. 使用三个 引号'''或双引号""" 创建多行字符串
  3. 使用r 创建原始 raw 字符串


6.3.1 定义单行字符串
void main(){

  // 单行字符串
  var str1 = '这是单行字符串';
  var str2 = "这是单行字符串";

  String str3 = '这是单行字符串';
  String str4 = "这是单行字符串";
    
  print(str1);
  print(str2);
  print(str3);
  print(str4);
}


6.3.2 定义多行字符串

定义多行字符串的字面量是三个单引号或三个双引号

语法

​ var str = ''' ''';

​ var str = """ """;

void main(){

  // 单行字符串
  var str1 = '''
    这是多行字符串
    这是多行字符串
  ''';
  var str2 = """
    这是多行字符串
    这是多行字符串
  """;

  String str3 = '''
    这是多行字符串
    这是多行字符串
  ''';
  String str4 = """
    这是多行字符串
    这是多行字符串
  """;
    
  print(str1);
  print(str2);
  print(str3);
  print(str4);
}


6.3.3 使用r创建字符串
void main(){
    String str = r"Hello World";
    print(str);  // Hello World
}

了解即可


6.3.4 字符串的拼接
void main(){

    String str1 = '你好';
    String str2 = "dart";
    // 1. 使用加好拼接字符串
    print(str1 + ' ' + str2 );  // 你好 dart

    // 2. 使用$ 拼接字符串
    print("$str1 $str2");    // 你好 dart

    // 3. 如果需要运算可以使用${}语法
    int num = 20;
    int num2 = 30;

    print("运算结果:${num + num2}"); // 运算结果:50
}


6.3.5 字符串和数字相互转换的方
void main(){
    // 字符串转为数字类型
    var one = int.parse("123");
    print(one);  // 123
    var point = double.parse("123.11");
    print(point);  // 123.11

    // 数字类型转字符串类型
    var str = 123.toString();
    print(str);    // 123
    var strpoint = 123.111.toString();
    print(strpoint);  // 123.111

    // double转字符串先得小数位数
    var strpoint2 = 123.161.toStringAsFixed(2);
    print(strpoint2); // 123.11
}


6.4 布尔类型

在dart中定义布尔类型的关键字是bool

布尔值只有个truefalse,它们都是编译时常量。

void main(){

  // 定义布尔类型
  bool flag1 = true;

  bool flag2 = false;
  
  print(flag1);
  print(flag2);
}

添加判断判断

void main(){

  // 定义布尔值
  bool flag = true;

   // 条件判断
  if(flag){
    print("真");
  }else{
    print("假");
  }
  
}

要注意dart条件判断没有隐式类型转换

void main(){

  var num = 123;
  var num2 = '123';

  if(num == num2){
    print("num和num2的类型和值都相等");
  }else{
    print("num和num2的类型或者值不相等");
  }
  
}

// 答应不相等, == 不会进行类型转换


6.5 集合类型 (List)

集合就像我们js里面的数组,只是叫法不一样

定义集合

字面量定义集合

void main(){

  // 定义集合
  // 1. 字面量的方式定义集合
  var list = ["张三","李四",'王五', 123];

  // 打印集合
  print(list);

  // 打印集合长度
  print(list.length);

  // 打印集合中的某一个值
  print(list[1]);
   
}

通过List 构造函数创建集合

void main(){

  // 定义集合

  // 2.  通过List 构造函数创建集合
  List list = new List();

  // 给集合添加内容
  list.add("张三");

  list.add(123);

  list.add(true);

  print(list);

}

指定集合内容的类型

void main(){

  // 定义集合
  // 3. 指定集合内容类型
  List list = new List<String>();
  // <String> 指定集合list里每一项只能为字符串类型

  list.add("张三");

  // 给list添加了一个不是字符串类型的值会报错
  list.add(123);

  print(list);
  
}


6.6 Maps类型

Map 通常也被称之为 字典或者 hash ,也是一个无序的集合,里面 包含一个 key-value 对。map 把 key 和 value 关联起来可以 方便获取数据。

有点类似于JS中的JSON对象, JS中的普通对象,属性可以不用加引号, dart中Maps类型属性一定要加引号(单引双引都可以)

所以注意, JavaScript 对象Object 不是 Maps。

void main(){

  // 定义Maps类型;
  // 1. 字面量定义map
  var map = {
    "name":"wuwei",
    'age': 18,
    "work": ["程序员", "外卖员"]
  };

  print(map);

  // map操作
  // map的操作不能使用点语法,只能使用中括号语法
  // 中括号语法单引双引都可以 
  print(map['name']);
  print(map["age"]);
  
}

除了字面量定压力Map外,还可以采用构造函数定义Map

void main(){

  // 定义Maps类型;

  // 2. 构造函数定义Map
  Map map = new Map();

  map['name'] = 'wuwei';
  map["work"] = ["程序员", "外卖员"];

  print(map);
}

注意点:

  1. 键和值都可以是任何类型的对象。
  2. 每个 键 只出现一次, 而一个值则可以出现多次


7. 判断数据类型

在dart中可以使用is关键字来判断数据类型

void main(){

  // 判断数据类型
  // 通过 is关键字
  // var str = '123';
  var str = 123;

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