Dart 基础

本文详细介绍了Dart编程语言的基础知识,包括环境搭建、语法特性如注释、变量、常量、数据类型、运算符、控制流、函数、异步编程、类与对象、枚举和库的使用。此外,还讲解了DartPad在线运行代码平台以及Dart的生态环境pub.dev。通过实例展示了Dart在字符串、列表、集合、映射等数据结构的操作,并探讨了Dart的异步处理和面向对象编程特性。
摘要由CSDN通过智能技术生成

Dart 资源网站

官网:

如果想要在线运行 Dart 代码,可以使用 DartPad

生态:

Dart 语言概览:https://dart.cn/samples
Dart 速查表:https://dart.cn/codelabs/dart-cheatsheet

环境搭建

Dart 的环境搭建主要有两种方式

  • 跟随 Flutter SDK 一起安装(推荐)
    从 Flutter 1.21 版本开始,Flutter SDK 会同时包含完整的 Dart SDK。

    即:如果你已经安装了 Flutter,就无需再下载 Dart SDK 了。
    例如,我在 flutter SDK 的 bin 目录下,也找到了 dart.bat

    在这里插入图片描述

  • 单独安装 Dart SDK
    参考官网文档:https://dart.dev/get-dart

Dart 环境搭建 – 绑定环境变量

在这里插入图片描述

Dart 语法基础

在这里插入图片描述
注释

  • 单行注释

    // 单行注释
    
  • 多行注释

    /* 多行注释 */
    
  • 文档注释

    /// 这是文档注释
    

    可以通过 dartdoc 将注释转成文档 (文档注释支持 markdown 语法)

变量

  • 变量是一个引用,根据Dart中万物皆对象原则,即变量存储的都是对象的引用,或者说它们都是指向对象。
  • 声明变量
    • 明确指定类型:int age = 18;
    • 不指定类型:var age = 18; 或 dynamic age = 18;
  • 变量名大小写敏感(age 和 Age 是俩个不同的变量)
  • 变量默认值是 null
  • Dart 变量的值不会进行隐式转换(null 不会自动转成 false)

常量

  • 声明常量
    • const age = 18;
    • final age =18;
  • const 与 final 的区别
    • const time=DateTime.now(); // 报错-无法将运行时的值分配给const变量
    • final time=DateTime.now(); // 成功-可以将运行时的值分配给final变量

Dart 数据类型

  • Number
    • num
    • int
    • double
  • String
  • Boolean
  • List
  • Set
  • Map
  • Rune (用于在字符串中表示 Unicode 字符)
  • Symbol

Number

void main() {
  // 声明整数
  int count = 3;
  print(count);

  // 声明浮点数
  double price = 3.7;
  print(price);

  // 声明数值类型
  num n1 = 3.7;
  print(n1);

  // 类型转换
  print(n1.toString());
  print(3.8.toInt()); // 向下取整

  // 四舍五入
  print(3.1415926.round());
  print(3.1415926.toStringAsFixed(4));

  // 返回余数
  print(10.remainder(4));

  // 数字比较: 0: 相同,1:大于,-1:小于
  print(10.compareTo(12));
  // 返回最大公约数
  print(12.gcd(18));

  // 科学计数法
  print(1000.toStringAsExponential(1));
}

String

void main() {
  // 声明字符串
  // var str1 = 'Hello, World'; // 单引号
  // print(str1);
  // var str2 = "你好,世界"; // 双引号
  // print(str2);

  String str1 = 'Hello, World'; // 单引号
  print(str1);
  String str2 = "你好,世界"; // 双引号
  print(str2);

  // 通过三个引号声明字符串
  String str3 = '''Hello
  World
  ''';
  print(str3);

  // 常见操作
  // 字符串拼接
  print(str1 + str2);
  print("$str1 $str2");

  // 字符串的分隔
  print(str1.split(''));

  // 字符串的裁切
  print('  abc   '.trim());

  // 判断字符串是否为空
  print(''.isEmpty);
  print(''.isNotEmpty);

  // 字符串替换
  print(str1.replaceAll('World', 'Dart'));
  // 支持正则替换
  print('h1k2d3n4n5n'.replaceAll(RegExp(r'\d+'), '_'));

  // 通过正则匹配手机号
  var isPhone = RegExp(r'^1\d{10}$');
  print(isPhone.hasMatch('13333333333'));
  print(isPhone.hasMatch('1333333333'));

  // 查找字符串
  print(str1.contains('e'));
  // 定位字符串
  print(str1.indexOf('e'));
}

Boolean
Dart 的类型安全不允许你使用类似if(nonbooleanValue)或者assert(nonbooleanValue)这样的代码检查布尔值。相反,你应该总是显示地检查布尔值,比如像下面的代码这样:

void main() {
  // 声明布尔类型
  bool flag1 = true;
  print(flag1);

  bool flag2 = false;
  print(flag2);

  // 显式地进行判断
  var flag3;
  if (flag3 == null) {
    print('真');
  } else {
    print('假');
  }

  // 一些特殊的判断场景
  var n1 = 0 / 0;
  print(n1);
  print(n1.isNaN);
}

List(列表)

  • 在 Dart 中数组由List对象表示。List 有两中声明方式
    • 字面量方式 List list = []; // 不设定元素的数据类型
    • List list = <int>[]; 限定元素的数据类型为 int
  • 构造函数形式
    • List list = new List.empty(growable: true); // 不限定长度的空列表
    • List list = new List.filled(3, 6); // 声明指定长度的填充列表
  • 扩展操作符 (…)
    • var list = [1,2,3];
    • var list2 = [0,…list] // [0,1,2,3]
  • 常用 API:

遍历 List

  • forEach()
    • 遍历列表
  • map()
    • 遍历并处理元素,然后生成新的列表
  • where()
    • 返回满足条件的数据
  • any()
    • 只要有一项满足条件,即返回 true
  • every()
    • 判断是否每一项都满足条件,都满足条件才返回 true

Set(集合)

  • Set 是一个无序的,元素唯一的集合
  • Set 有字面量和构造函数两种声明方式(字面量中用大括号)
  • 无法通过下标取值
  • 具有集合特有的操作
    • 列如:求交集,并集,差集等
  • 常用 API:https://api.dart.dev/stable/dart-core/Set-class.html

Map(映射)

  • Map 是一个无序的 key-value (键值对)集合,就是大家熟知的字典(dictionary)或者哈希(hash)。
  • 声明方式
    • var map = { key1: value1, key2: value2 };
    • var map = new Map();
    • map[‘key’] = value;
  • 常用 API:https://api.dart.dev/stable/dart-core/Map-class.html

在这里插入图片描述

Dart 运算符

地板除
先进行除法运算,然后向下取证

assert(5 ~/ 2 == 2); // 结果是一个整数

类型判断运算符
在这里插入图片描述
避空运算符

??,左侧表达式为空时,返回右边的表达式。

print(1 ?? 3); // 返回 1
print(null ?? 12); // 返回 12

var foo;
// foo = 6;
print(foo ?? 0); // 如果 foo 是 null,则返回 0

??=变量为空时,才为其赋值:

var a;
// if (a == null) {
//   a = 3;
// }
a ??= 3;
print(a);
a ??= 6; // 如果 a 不是 null。则赋值失败
print(a);

条件属性访问
要保护可能会为空的属性的正常访问,请在点(.)之前加一个问号(?)。

var m = new Map();
print(m.length);
var obj;
// print(obj.length); // The getter 'length' was called on null.
print(obj?.length);

级联运算符
要对同一对象执行一系列操作,请使用级联(…)。我们都看到过这样的表达式:

// 调用myObject的someMethod方法,返回someMethod的返回值
myObject.someMethod()

//调用myObject的someMethod方法,返回myObject对象的引用
myObject..someMethod()

级联可以让你在同一个对象上连续调用多个对象的变量或方法。例如:

Set s = new Set();
s.add(1);
s.add(2);
s.add(3);
s.remove(2);
print(s);

使用级联:

Set s = new Set();
s..add('a')..add('b')
 ..add('c')
 ..remove('b');
print(s);

Dart 函数

声明函数

  • Dart 中声明函数,不需要 function 关键字
  • 箭头函数
    • Dart 中的箭头函数中,函数体只能写一行且不能带有结束的分号
    • Dart 中的箭头函数,只是函数的一种简写方式
  • 匿名函数
  • 立即执行函数

函数参数

  • 必填参数
    • 参数类型 参数名称
  • 可选参数
    • 放在必选参数后面
    • 通过中括号包裹起来
    • 带默认值的可选参数
  • 命名参数
    • 用大括号包裹起来
    • 调用函数时,命名参数的名称与声明函数中的名称保持一致
  • 函数参数
void main() {
  // 必填参数
  String userInfo(String name) {
    return '你好:$name';
  }
  String res = userInfo('张三');

  // 可选参数
  String userInfo(String name, [int age = 0]) {
    return '你好:$name, 年龄:$age';
  }

  String res = userInfo('张三', 20);
  print(res);

  // 命名参数
  String userInfo(String name, {int age = 0}) {
    return '你好:$name, 年龄:$age';
  }

  // 命名参数调用时,需要与声明时的形参一致
  String res = userInfo('张三', age: 20);
  print(res);

  // 函数参数
  var myPrint = (value) {
    print(value);
  };
  List fruits = ['苹果', '香蕉', '猕猴桃'];
  // 将匿名函数 myPrint 传递给函数 forEach
  fruits.forEach(myPrint);
}

在这里插入图片描述
异步函数

  • JavaScript 中的异步调用可以通过 Promise 来实现
    • async 函数返回一个 Promise。awate 用于等待 Promise
  • Dart 中,异步调用通过 Future 来实现
    • async 函数返回一个 Future 。awate 用于等待 Future
  • Future 详情

对象与类

简介

  • 类是通过 class 声明的代码段,包括属性和方法。
    • 属性:用来描述类的变量
    • 方法:类中的函数称为类的方法
  • 对象是类的实例化结果 (var obj = new MyClass())
  • 编程方式
    • 面向对象编程 (OOP)
    • 面向过程编程 (POP)

构造器(构造函数)

  • 默认构造函数
    • 与类同名的函数,在实例化时,自动被调用
  • 命名构造函数
    • 在类中使用命名构造器实现多个构造器,可以提供额外的清晰度:
  • 常量构造函数
    • 如果生成类的对象不会变,您可以通过常量构造函数使这些对象成为编译时常量
  • 工厂构造函数
    • 通过 factory 关键字声明,工厂函数不会自动生成实例,而是通过代码来决定返回的实例
    class Person {
      String name;
    
      static Person instance;
    
      // 工厂构造函数
      factory Person([String name = '刘备']) {
        // 工厂构造函数中,不能使用 this 关键字
        // print(this.name);
        if (Person.instance == null) {
          // 第一次实例化
          Person.instance = new Person.newSelf(name);
        }
        // 非第一次实例化
        return Person.instance;
      }
    
      // 命名构造函数
      Person.newSelf(this.name);
    }
    
    void main() {
      // 实例化操作
      Person p1 = new Person('关羽');
      print(p1.name);
    
      Person p2 = new Person('张飞');
      print(p2.name);
    
      print(p1 == p2);
    }
    

访问修饰

  • Dart 与 TypeScript 不同,没有访问修饰符( public、protected和private)
  • Dart 类中,默认的访问修饰符是公开的(即 public)
  • 如果属性或方法以下划线 (_) 开头,则表示私有(即 private)
  • 只有把类单独抽离出去,私有属性和方法才起作用

getter 与 setter

  • Getter(获取器)是通过 get 关键字修饰的方法
    • 函数没有小括号,访问时也没有小括号(像访问属性一样访问方法)
  • Setter (修改器)是通过 set 关键字修饰的方法
    • 访问时像设置属性一样给函数传参

初始化列表

  • 初始化列表的作用是,在构造函数中给定属性的默认值

    class Rect {
      int height;
      int width;
      
      // 初始化列表
      Rect() : height = 4, width = 20 {
        print('${this.height} -- ${this.width}');
      }
    }
    
    class Point {
      double x, y, z;
    
      Point(this.x, this.y, this.z);
    
      // 初始化列表的特殊用法(重定向构造函数)
      Point.twoD(double x, double y) : this(x, y, 0);
    }
    

static

  • static 关键字用来指定静态成员
    • 通过 static 修饰的属性是静态属性
    • 通过 static 修饰的方法是静态方法
  • 静态成员可以通过类名称直接访问(不需要实例化)
    • 实例化是比较消耗资源的,声明静态成员,可以提高程序性能
  • 静态方法不能访问非静态成员,非静态方法可以访问静态成员
    • 静态方法中不能使用 this 关键字
    • 不能使用 this 关键字访问静态属性

元数据

  • 元数据以@开头,可以给代码标记一些额外的信息
    • 元数据可以用来库,类,构造器,函数,字段,参数或变量声明的前面
  • @override (重写)
    • 某方法添加了该注解后,表示重写了父类中的同名方法
  • @required (必填)
    • 可以通过 @required 来注解 Dart 中的命名参数,用来指示它是必填参数
  • @deprecated (弃用)
    • 若某类或某方法加上该注解之后,表示此方法或类不再建议使用

继承

  • 可以根据先后关系,将类分为父类和子类
  • 子类通过 extend 关键字继承父类
    • 继承后子类中可以使用父类中可见的内容(属性和方法)
  • 子类中可以通过 @overried 元数据来标记 “覆写” 方法
    • “覆写”方法:子类中与父类中同名的方法
  • 子类中,可以通过 super 关键字来引用父类中,可见的内容
    • 属性
    • 方法(普通构造函数,命名构造函数)

抽象类

  • 抽象类是用 abstract 关键字修饰的类
  • 抽象类的作用是充当普通类的模板,约定一些必要的属性和方法
  • 抽象方法是指没有方法体的方法
    • 抽象类中一般都有抽象方法,也可以没有抽象方法
    • 普通类中不能有抽象方法
  • 抽象类不能被示列化 (new)
  • 抽象类可以被普通类继承 (extend)
    • 如果普通类继承抽象类,必须实现抽象类中的所有抽象方法
  • 抽象类还可以充当接口被实现 (implements)
    • 如果把抽象类当做接口实现的话,普通类必须实现抽象类里面定义的所有属性和方法

接口

  • 接口在 Dart 中就是一个类(只是用法不同)
    • 与 TypeScript 不同,TypeScript 中的接口需要用 interface 关键字声明;Dart 中不需要
    • 接口可以是任意类,但一般使用抽象类做接口
  • 一个类可以实现多个接口(implements),多个接口用逗号分隔
    • class Phone implements Processor, Camera { … }
    • 接口可以看成一个个小零件。类实现接口就相当于组装零件
  • 普通类实现接口后,必须重写接口中的所有属性和方法

混入(Mixin)

  • 混入(Mixin)是一段公共代码。混入有两种声明方式:
    • 将类当作混入 class MixinA { … }
      • 作为 Mixin 的类只能继承 Object,不能继承其他类
      • 作为 Mixin 的类不能有构造函数
    • 使用 mixin 关键字声明 mixin MinxinB { … }
  • 混入(Mixin)可以提高代码复用率,普通类可以通过 with 来使用混入
    • class Myclass with MicxinA MixinB { … }
  • 使用多个混入时,后引入的混入会覆盖之前引入中的重复内容
    • MixinA 和 MinxinB 都有 hello() 方法,Myclass 会使用 MixinB 中的

泛型(Generics)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
枚举类型

  • 枚举数量固定的常量值,通过 enmu 关键字声明
    enum Color { red, green, blue}
  • 枚举的values常量,可以获取所有枚举值列表( list )
    List colors = Color.values;
  • 可以通过 index 获取值的索引
    assert(Color.green.index==1);

Dart 库与生态

简介

  • Dart 中的库就是具有特定功能的模块
    • 可能包含单个文件,也可能包含多个文件
  • 按照库的作者进行划分,可以将库分为三类
    • 自定义库:(工程师自己写)
    • 系统库:(Dart 中自带的)
    • 第三方库:(Dart 生态中的)
  • Dart 生态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
系统库

  • 系统库(也叫核心库)是 Dart 提供的常用内置库
    • 不需要单独下载,就可以直接使用
  • 引入:
    import ‘dart:库名’;
    • import ‘dart:core’; // 会自动引入 (无需手动引入)
  • 系统库列表
  • https://dart.cn/guides/libraries

第三方库(包)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值