Dart常用核心知识

Dart简述
Dart 是一个为全平台构建快速应用的客户端优化的编程语言,免费且开源。
Dart是面向对象的、类定义的、单继承的语言。它的语法涵盖了多种语言的语法特性,如C,JavaScirpt, Java, Swift等语言,可以转译为JavaScript,支持接口(interfaces)、混入(mixins)、抽象类(abstract classes)、具体化泛型(reified generics)、可选类型(optional typing)和sound type system。
下面整理了Dart这门语言的核心知识点。
1.变量声明
2.字符串
3.集合
4.函数
5.赋值运算符
6.面向对象
7.枚举
8.库的使用
 
1.变量的声明
dart变量的声明有两种,常量和变量。使用常量可以保证在定义一个变量后,如果后面赋值了不同的类型的值,会在编译期报错,提高安全性。
常量
1.const编译时常量,这种常量值要在编译前确定。
2.final运行时常量,这种常量值可以在运行时再确定。
变量
1.显示声明,如使用String name定义变量。
2.var类型推导,有编译器自动推导。虽然使用的var定义变量,此时的变量依然是确定的类型。
void main(List<String> args) {
  print("Hello Dart");

// 显示声明
String name = 'jack';
// 类型推断:类型推断的,也是有类型的。不同类型之间不能赋值。

// 类型推断变量
var age = 20;
age = 30;
// age = 30.3;

// 编译期常量
const school = '北京大学';
// 运行时常量
final local = DateTime.now();


const p1 = const Person('Tom');
const p2 = const Person('Tom');
const p3 = const Person('LiLei');

print(identical(p1, p2));
print(identical(p1, p3));

}


class Person {
  final String name;
  // 构造函数传参直接赋值到name属性上。
  const Person(this.name);
}

 

2.字符串
定义字符串有三种方式:单引号,双引号,三引号。
字符串的拼接规则和shell语法一样,$变量名后面没有其他符号时使用$变量名,后面紧跟其他符号产生歧义时,使用${变量名}
void main(List<String> args) {
  // 定义字符串三种方式:单引号,双引号,三引号
  var str1 = 'abc';
  var str2 = "def";
  var str3 = """
      ghi
      jkl
      mn
  """;
  print(str3);

  // 字符串拼接: 拼接规则和shell很相似
  var name = 'jack';
  var age = 30;
  var height = 190.3;

  var msg1 = "name is $name, age is ${age}, height is ${height}, height Type is ${height.runtimeType}";
  print(msg1);

}

 

3.集合
dart中有三种集合, dart在集合中广泛使用泛型来表示集合中存放的是什么类型。
1.列表List: 使用[‘ABC’]进行定义
2.集合Set: 使用{'abc'}, 可以对列表List去重
3.哈希Map: 使用{'name': value},使用的键值对进行定义
void main(List<String> args) {
  // dart中没有关键字定义接口,默认情况下,所有的class都是隐式接口
  // dart在集合中广泛使用泛型来表示集合中存放的是什么类型。

  // 1.列表List
  var names = ['abc', 'cba', 'nba', 'cba', 'abc'];
  names.add('hhh');
  print(names);
  print(names.runtimeType);

  // 2.集合Set
  var movies = {'星际穿越', '大话西游', '盗梦空间'};
  names = Set<String>.from(names).toList();
  print(names);
  print(movies);


  // 3.映射Map
  // 映射的Key应该是可以求出hash值的。
  var info = {
    'name': 'jack',
    'age': 30
  };
  Map;
  print(info);
  print(info.runtimeType);
  
}

 

4.函数
函数的定义
dart 函数的形式和 C 语言相似,形式为:返回值 函数名(参数) {函数体}
其中返回值部分可以省略有编译器自动推导,但是推荐写上,方便开发人员理解。
dart 中没有函数的重载。
函数的可选参数
可选参数类型有:位置可选参数 、命名可选参数两种。
位置可选参数形式为:[int age, double height],实参和形参在进行匹配时,是根据位置匹配的。
命名可选参数:{int age, double height},实参和形参在进行匹配时,需要根据名称进行设置。
可选参数可以有默认值,必传参数不能设置默认值。
函数是一等公民
一等公民是很灵活的,可以作为参数和返回值。
OC 中使用 Block 实现这一特性。
匿名函数
因为 dart 中函数为一等公民,所以在函数作为参数进行传参时,可以将函数写成匿名函数的形式。
参数中的匿名函数有两种形式:
匿名函数体是单条语句时,可以用是箭头函数表示
testFunc(() => print('箭头匿名函数,只能有一条语句') );
当匿名函数体中的语句多行时,使用下面的形式
// 多条语句
testFunc(() {
    print('匿名函数被调用');
});
匿名传参,参数需要定义为完整的函数签名,也可以使用下面类型定义的方式。
typedef Calculate = int Function(int num1, int num2);
void testFoo2(Calculate cal) {
  cal(10, 10);
}

 

void main(List<String> args) {
  print(sayHi(10, 20));

  // 顺序可选参数,传参的顺序必须和定义顺序相同
  sayHello1('jack', 30);
  // 命名可选参数,传参需要带定义的名称
  sayHello2('jack', age: 30);
  testFunc(foo);
}

// 1.函数的定义
// 返回值类型int 可以省略,但是推荐保留
int sayHi(int height, int age) {
  return age + height;
}


// 2.函数的可选参数
/*
   dart中没有函数的重载
   可选参数:位置可选参数 - 命名可选参数
   可选参数可以默认值,必传参数不需要默认值
*/
// 位置可选参数
void sayHello1(String name, [int age, double height]) {

}

// 命名可选参数
void sayHello2(String name, {int age, double height}) {

}
// 命名可选参数带默认值
void sayHello3(String name, {int age, double height = 12}) {

}

// 3.函数是一等公民
/*
   一等公民是很灵活的,可以作为参数和返回值。
   OC中使用Block实现这一特性
*/

void testFunc(Function foo) {
  foo();
}
void foo() {
  print('foo 函数被调用');
}

// 4.匿名函数
void testFunc2() {
  // 多条语句
  testFunc(() {
    print('匿名函数被调用');
  });

  // 单条语句
  testFunc(() => print('箭头匿名函数,只能有一条语句') );

  // 匿名函数传参
  /*
    匿名传参,参数需要定义为完整的函数签名:void testFoo(int foo(int num1, int num2)) {}
  */
  testFoo((num1, num2) => num1 + num2);
  testFoo2((num1, num2) => num1 + num2);

  // 匿名返回值
  var foo3 = testFoo3();
  foo3(3, 3);
}

void testFoo(int foo(int num1, int num2)) {
  print(foo(10, 20));
}
typedef Calculate = int Function(int num1, int num2);
void testFoo2(Calculate cal) {
  cal(10, 10);
}

Calculate testFoo3() {
  return (int num1, int num2) => num1 * num2;
}

 

5.赋值运算符

Dart中比较特别的运算符有: ??=, ??, 级联运算符
??=
如果运算符 ??=前面的变量为null就执行后面的=赋值操作,如果pro有值就不执行后面的操作。
特点:可能有赋值操作。
使用场景如:pro ??= name;
??
??是?:三目运算符号的简写, 如果前面的变量有值则取前面的值,如果前面的值为空就取后面的值。
特点:一定有赋值操作。
使用场景如:school = pro ?? '没人上学';
级联运算符..
级联运算符可以连续对实例对象调用方法或属性
void main(List<String> args) {

  // ??=: 如果前面的pro为null就执行后面的=赋值操作,如果pro有值就不执行后面的操作。
  // 可能有赋值操作
  var name = 'jim';
  var pro = null;
  pro ??= name;
  print(pro);

  // ??: 是?:三目运算符号的简写, 如果前面的变量有值则取前面的值,如果前面的值为空就取后面的值。
  // 一定有赋值操作
  var school = '小学';
  school = pro ?? '没人上学';
  print(school);


  // 级联运算符:可以连续调用..方法
  var p = Person()
      ..name = 'jim'
      ..eat()
      ..run();
  p.eat();

}

class Person {
  var name;
  void eat() {

  }

  void run() {

  }
}
 
6.面向对象
1.类的基本定义
dart中的类默认继承在Object类,创建的实例对象可以调用Object中的方法。
如果不自定义结构函数,系统会给类自动创建一个空参数的构造函数。
// 类默认是继承自Object的,应用创建的对象是可以使用Object中的方法的。
class Person {
  String name;
  int age;
}
2.类的构造函数
dart中类的构造函数有三种:
a.用户没有自定义构造函数时,系统会默认实现一个空参数的构造函数
b.普通构造函数,通过便捷赋值,直接初始化属性值
Student(this.name, this.age);

c.命名构造函数,因为Dart中不支持函数重载,所以出现了命名构造函数来作为构造函数

Student.withNameAgeHeight(this.name, this.age, this.height);

Student.withMap(Map<String, dynamic> map) {
    this.name = map['name'];
    this.age = map['age'];
    this.height = map['height'];
};

dynamic、var、Object的区别?

var是类型推断。
dynamic是类型声明,相当于Swift中的Any,它是一个具体类型的声明,如String。
Object可以父类指向子类对象。
dynamic是运行时报错, Object是编译时报错。
 
3.类的初始化列表
dart的构造函数的结构体执行时,是在构造函数执行后,所以对于final属性,它必须在构造函数执行时进行执行。所以此时的执行时间需要在结构体执行,故:它的执行时间是在():后面的初始化列表里执行。
初始化列表:里面执行不仅可以包含编辑期静态返回值,还可以包含动态调用返回值。如:Color.blue
可选命名表达式: 只能有编译器静态赋值表达式,如:int age = temp ?? 20
// 3.类的初始化列表
class Teacher {
  final String name;
  final int age;

  // Teacher(this.name, {int age = 10, String color}): this.color = color ?? '' {
  // }
  Teacher():this.name = 'jc', this.age = 10 {
  }
}
4.构造函数重定向
当一个类中定义多个构造函数时,可以在普通构造函数的初始化列表中调用其他命名构造函数。
class Doctor {
  int age;
  String name;

  // 构造函数重定向
  Doctor(String name): this._internal(name, 10);
  // 命名构造函数
  Doctor._internal(String name, int age);
}
5.常量构造函数
使用常量构造函数创建的常量对象,如果对象的属性值一样时,返回的实例对象内存地址是一样的,返回的是同一个对象。
// 5.常量构造函数,相同的属性只有一个内存对象。
class Apple {
  final String name;
  final int age;

  const Apple(this.name, this.age);
}
6.工厂构造函数
工厂构造函数最大的特点是可以手动返回对象。
普通构造函数与工厂构造函数的区别:
普通构造函数不需要写return 会自动返回实例对象。
工厂构造函数需要写return 手动返回实例对象。
// 6.工厂构造函数:最大的特点可以手动返回一个对象。

class Orange {
  String name;
  String color;
  static final Map<String, Orange> _nameCache = {};
  static final Map<String, Orange> _colorCache = {};
  
  factory Orange.withName(String name) {
    if (_nameCache.containsKey(name)) {
      return _nameCache[name];
    } else {
      final p = Orange(name, 'red');
      _nameCache[name] = p;
      return p;
    }
  }
  Orange(this.name, this.color);
}
7.Setter, Getter
在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。
// 7.Setter, Getter进行属性监听
// 使用方式是: var e = Elephone(); e.setName('jim'); e.getName
class Elephone {
  String name;
  // 在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。
  String _age;

  // setter
  set setName(String name) {
    this.name = name;
  }
  // getter
  String get getName {
    return name;
  }

}
8.继承
子类继承父类时,父类有构造函数时,需要在子类的参数列表中进行调用,进行初始化。
// 8.继承:父类的构造函数要在子类的初始化列表中进行调用。
class Animal{
  String name;
  Animal(this.name);

  void eat() {
    print('eatting');
  }
}

class Dog extends Animal {
  int age;
  // 父类有构造函数时,需要在参数列表中进行调用,初始化。
  Dog(this.age, String name): super(name);
}
9.抽象类
抽象类在使用时有以下特点:
a.子类继承抽象父类,父类的接口方法必须实现,它们都是必选项。因为dart中没有option可选项。
b.抽象类不能被实例化。
c.系统调用抽象类Map进行实例化的过程分析
  Map是一个抽象类,而可以调用Map()产生实例对象的原因是因为调用的Map()是Map抽象类的工厂方法 external factory Map();
  external关键字 是一个方法存在的声明,表示此方法已经存在,但不在这里实现。这样实现和声明分离
  的好处是,可以在实现的地方使用runtimeType集中处理不同平台逻辑,而通过方法接口声明在不同的平台调用。
  在方法具体实现的地方使用@patch修饰。
// 9.抽象类
abstract class Shape {
  int getArea();
  String getInfo() {
    return '形状';
  }

  void testMap() {
    final m = Map();
    print(m.runtimeType);
  }
}

class Rectangle extends Shape {
  @override
  int getArea() {
    return 20;
  }
}
10.dart隐式接口
dart中定义的class同时也可以当接口使用,可以说class定义的即是类,也是接口。当它做为类使用时,里面定义的方法不必须让子类实现。当它做接口时,里面定义的方法都需要被重新实现。
dart是单继承语言。
// 10.dart隐式接口:dart中定义的class同时也可以当接口使用。
class Runner {
  void run() {
    print('running');
  }
}

class Fly {
  void fly() {
    print('fly');
  }
}

class SuperMan extends Animal implements Runner, Fly {
  SuperMan(String name):super(name);

  // 1.接口实现
  @override
  void run() {
    // TODO: implement run
  }

  @override
  void fly() {
    // TODO: implement fly
  }

  // 2.方法重写
  @override
  void eat() {
    // TODO: implement eat
    super.eat();
  }
}
11.混入mixin
dart是单继承语言。
当出现需求想要同时拥有多个类中的方法和属性时,可以通过 混入mixin来间接实现多继承。
可以同时引入多个mixin类中的方法。
dart是单继承, 如果要想同时引入多个mixin类中的方法,则可以定义多个mixin类来引入。
定义用mixin,使用用with。
// 11.混入mixin
mixin Play {
  void play() {
    print('play');
  }
}

mixin Jump {
  void jump() {
    print('jump');
  }
}

class Robbit extends Animal with Play, Jump {
  Robbit(String name):super(name);

  @override
  void eat() {
    // TODO: implement eat
    super.eat();
  }
}
12.static 类属性,类方法
可以通过static静态声明来定义类属性和类方法/*
  12.static 类属性,类方法
*/

class SuperWoman {
  // 成员变量,成员方法
  var name;
  void fly() {

  }

  // 静态/类变量,静态/类方法
  static var flyYear;
  static void run() {

  }
}
 
void main(List<String> args) {
  // 虽然dart支持函数式开发,但是大部分使用的是面向对象开发。

  var p0 = Person('jim', 22);
  print(p0.toString());

  var s0 = Student.withMap({
    'name': 'jack',
    'age': 18,
    'height': 33.3
  });
  print(s0);

}

// 1.类的基本定义
// 类默认是继承自Object的,应用创建的对象是可以使用Object中的方法的。
class Person {
  String name;
  int age;

  // Person(String name, int age) {
  //   this.name = name;
  //   this.age = age;
  // }

  // 语法糖
  Person(this.name, this.age); 

}

// 2.类的构造函数
class Student {
  String name;
  int age;
  double height;

  // a.普通的构造方法
  Student(this.name, this.age);
  // b.命名构造函数:因为Dart中不支持函数重载,所以出现了命名构造函数来作为构造函数

  Student.withNameAgeHeight(this.name, this.age, this.height);

  /*
    dynamic和Object的区别
    dynamic是类型声明,var是类型推断,它是一个具体类型的声明,如String。
    dynamic是运行时报错
    Object是编译时报错
    Object可以父类指向子类对象。

    Object obj = 'hello';
    print(obj.toString(1));

  */
  Student.withMap(Map<String, dynamic> map) {
    this.name = map['name'];
    this.age = map['age'];
    this.height = map['height'];
  }


  // c.重新类的描述方法
  @override
  String toString() {
    // TODO: implement toString
    return "$age, $name, $height";
  }
}


// 3.类的初始化列表
class Teacher {
  final String name;
  final int age;

  /*
    构造函数的结构体执行时,是在构造函数执行后,所以对于final属性,它必须在构造函数执行时进行执行
    所以此时的执行时间就是在结构体执行时,故:它的执行是在():后面的初始化列表里执行。

    初始化列表:里面执行不仅包含编辑期静态返回值,还可以包含动态调用返回值。如:Color.blue
    可选命名表达式: 只能有赋值表达式,如:int age = temp ?? 20
  */
  // Teacher(this.name, {int age = 10, String color}): this.color = color ?? '' {

  // }

  Teacher():this.name = 'jc', this.age = 10 {

  }
}


// 4.构造函数重定向
class Doctor {
  int age;
  String name;

  // 构造函数重定向
  Doctor(String name): this._internal(name, 10);
  // 命名构造函数
  Doctor._internal(String name, int age);
}

// 5.常量构造函数,相同的属性只有一个内存对象。
class Apple {
  final String name;
  final int age;

  const Apple(this.name, this.age);
}

// 6.工厂构造函数:最大的特点可以手动返回一个对象。
/*
  普通构造函数不需要写return 会自动返回实例对象。
  工厂构造函数需要写return 手动返回实例对象。
  static:全局静态方法,类方法。
*/

class Orange {
  String name;
  String color;
  static final Map<String, Orange> _nameCache = {};
  static final Map<String, Orange> _colorCache = {};
  
  factory Orange.withName(String name) {
    if (_nameCache.containsKey(name)) {
      return _nameCache[name];
    } else {
      final p = Orange(name, 'red');
      _nameCache[name] = p;
      return p;
    }
  }

  Orange(this.name, this.color);


}


// 7.Setter, Getter进行属性监听
// 使用方式是: var e = Elephone(); e.setName('jim'); e.getName
class Elephone {
  String name;
  // 在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。
  String _age;

  // setter
  set setName(String name) {
    this.name = name;
  }
  // getter
  String get getName {
    return name;
  }

}


// 8.继承:父类的构造函数要在子类的初始化列表中进行调用。
class Animal{
  String name;
  Animal(this.name);

  void eat() {
    print('eatting');
  }
}

class Dog extends Animal {
  int age;
  // 父类有构造函数时,需要在参数列表中进行调用,初始化。
  Dog(this.age, String name): super(name);
}


// 9.抽象类
// a.子类继承抽象父类,父类的接口方法必须实现,没有option可选项。
// b.抽象类不能实例化
/*
  c.系统抽象类Map实例化分析
  Map是一个抽象类,而可以调用Map()产生实例对象的原因是因为
  调用的Map()是Map抽象类的工厂方法external factory Map();

  external 是一个方法存在声明,表示此方法已经存在,但不在这里实现。这样实现和声明分离
  的好处是,可以在实现的地方使用runtimeType集中处理不同平台逻辑,而通过方法接口声明在不同的平台
  调用。 
  实现的地方使用@patch修饰。
*/
abstract class Shape {
  int getArea();
  String getInfo() {
    return '形状';
  }

  void testMap() {



    final m = Map();
    print(m.runtimeType);
  }
}

class Rectangle extends Shape {
  @override
  int getArea() {
    return 20;
  }
}



// 10.dart隐式接口:dart中定义的class同时也可以当接口使用。
/*
  dart中没有interface/ protocal这样专门定义接口的关键字
  dart中定义的class 同时也具有接口的功能,把class当接口使用时,class中定义的方法必须要全部实现。
  dart是单继承
*/

class Runner {
  void run() {
    print('running');
  }
}

class Fly {
  void fly() {
    print('fly');
  }
}

class SuperMan extends Animal implements Runner, Fly {
  SuperMan(String name):super(name);

  // 1.接口实现
  @override
  void run() {
    // TODO: implement run
  }

  @override
  void fly() {
    // TODO: implement fly
  }

  // 2.方法重写
  @override
  void eat() {
    // TODO: implement eat
    super.eat();
  }
}

// 11.混入mixin
/*
  混入mixin间接实现多继承,可以同时引入多个mixin类中的方法
  dart是单继承, 如果要想同时引入多个mixin类中的方法,则可以定义多个mixin类来引入
  定义用mixin
  使用用with
*/
mixin Play {
  void play() {
    print('play');
  }
}

mixin Jump {
  void jump() {
    print('jump');
  }
}

class Robbit extends Animal with Play, Jump {
  Robbit(String name):super(name);

  @override
  void eat() {
    // TODO: implement eat
    super.eat();
  }
}


/*
  12.static 类属性,类方法
*/

class SuperWoman {
  // 成员变量,成员方法
  var name;
  void fly() {

  }

  // 静态/类变量,静态/类方法
  static var flyYear;
  static void run() {

  }
}

 

7.枚举
Dart相比JavaScript增加了枚举类型。
void main(List<String> args) {
  var color = Colors.red;

  switch (color) {
    case Colors.blue:
      print('蓝色');
      break;
    case Colors.red:
      print('红色');
      break;
    case Colors.yellow:
      print('黄色');
      break;
    default:
  };

  print(Colors.values);    
}

enum Colors {
  red,
  blue,
  yellow
}
 
8.库的使用
dart中,一个文件就是一个模块或一个库。
dart中的库有三种:系统库,自定义库,第三方库。
系统库:dart中的Core核心库无需导入,默认导入。如使用的Map
如果使用其他专门功能,就导入专门的库,如:
  import 'dart:async';
  import 'dart:io';
  import 'dart:库的名称';
自定义库:导入方式
import '08_dart_自定义库_utils/math_utils.dart'
  如果自定义库和当前模块或系统库方法名重复,可以是as重命名来区分
  import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
第三方库:导入方式
  import 'package:http/http.dart' as http;
注意
1.as关键字可以给库起别名
2.默认情况下,导入一个库时会导入库中的所有内容,此时可以使用修饰词声明部分导入
show: 声明要导入的部分
hide: 声明要隐藏的部分
  import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
  import '08_dart_自定义库_utils/math_utils.dart' show sum;
  import '08_dart_自定义库_utils/math_utils.dart' hide sub ;
3.export统一导出一类库文件,当一个目下有多个工具库时,可以统一放到一个文件中,集中导入防止每个都导入一次
export 'io_utils.dart';
export 'math_utils.dart'; 

4.库文件中的私有方法是_开头的方法。

5.flutter项目第三方库管理文件pubspec.yaml, 然后执行pub get进行更新。
    name: zhoufei
    description: a dart lib
    dependencies:
      http: ^0.12.0

 

import 'dart:math';
import 'dart:convert' as convert;

import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
// import '08_dart_自定义库_utils/math_utils.dart' show sum;
// import '08_dart_自定义库_utils/math_utils.dart' hide sub ;

import 'package:http/http.dart' as http;



void main(List<String> args) async {
  final num1 = 10;
  final num2 = 20;
  print(min(num1, num2));

  MathUtils.sub(num1, num2);

   var url =
      Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': '{http}'});

  // Await the http get response, then decode the json-formatted response.
  var response = await http.get(url);
  if (response.statusCode == 200) {
    var jsonResponse =
        convert.jsonDecode(response.body) as Map<String, dynamic>;
    var itemCount = jsonResponse['totalItems'];
    print('Number of books about http: $itemCount.');
  } else {
    print('Request failed with status: ${response.statusCode}.');
  }
  
}

/*
  dart中,一个文件就是一个模块或一个库
  注意:
  1.as关键字可以给库起别名
  2.默认情况下,导入一个库时会导入库中的所有内容,此时可以使用修饰词声明部分导入
    show: 声明要导入的部分
    hide: 声明要隐藏的部分
  import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
  import '08_dart_自定义库_utils/math_utils.dart' show sum;
  import '08_dart_自定义库_utils/math_utils.dart' hide sub ;
  3.export统一导出一类库文件,当一个目下有多个工具库时,可以统一放到一个文件中,集中导入防止每个都导入一次
    export 'io_utils.dart';
    export 'math_utils.dart'; 
  4.库文件中的私有方法是_开头的方法。  
  5.flutter项目第三方库管理文件pubspec.yaml, 然后执行pub get进行更新。
    name: zhoufei
    description: a dart lib
    dependencies:
      http: ^0.12.0


  系统库
  dart中的Core核心库无需导入,默认导入。如使用的Map
  如果使用其他专门功能,就导入专门的库,如:
  import 'dart:async';
  import 'dart:io';
  import 'dart:库的名称';


  自定义库
  导入方式
  import '08_dart_自定义库_utils/math_utils.dart'
  如果自定义库和当前模块或系统库方法名重复,可以是as重命名来区分
  import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;

  第三方库
  导入方式
  import 'package:http/http.dart' as http;

*/

 

 
posted @ 2023-01-25 22:07  滴水微澜  阅读(207)  评论(0编辑  收藏  举报