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.http('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;

*/

 

 
本文转载于网络 如有侵权请联系删除

相关文章

  • React v18.x 在 react-router v6 使用 lazy 动态加载组件实现

    对于直接使用React.lazy来说,基本上是没有问题的,但是当在ts下,将导入的组件放到router的elment属性下会报错,一般为类型不匹配而且对于lazy来说,是react提供的一个功能,并且需要配置fallback来确保当组件找不到或者正在获取时的替换组件。那么我们可以创建一个lazy-import-component.tsx来共用importGlobalLoadingfrom'@main/components/global-loading/global-loading'; importReact,{LazyExoticComponent}from'react'; exportconstLazyImportComponent=(props:{ lazyChildren:LazyExoticComponent<()=>JSX.Element>; })=>{ return( <React.Suspensefallback={<GlobalLoading/>}> <props.lazyC

  • 双线性插值算法推导及代码实现

    大家好,又见面了,我是你们的朋友全栈君。双线性插值,是一种比较重要的插值方法,尤其在数字图像处理领域。本篇博文分为三个部分:一是双线性插值的算法推导,二是双线性插值的算法实现,三是算法的运行结果。一双线性插值的算法推导二代码实现(matlab)function[out]=bilinearInterpolation(im,out_dims) in_rows=size(im,1); in_cols=size(im,2); out_rows=out_dims(1); out_cols=out_dims(2); S_R=in_rows/out_rows; S_C=in_cols/out_cols; [cf,rf]=meshgrid(1:out_cols,1:out_rows); rf=rf*S_R; cf=cf*S_C; r=floor(rf); c=floor(cf); r(r<1)=1; c(c<1)=1; r(r>in_rows-1)=in_rows-1; c(c>in_cols-1)=in_cols-1; delta_R=rf-r; delta_C=

  • 自己动手写一个GDB|设置断点(原理篇)

    在上一篇文章《自己动手写一个GDB|基础功能》中,我们介绍了怎么使用ptrace()系统调用来实现一个简单进程追踪程序,本文主要介绍怎么实现断点设置功能。什么是断点当使用GDB调试程序时,如果想在程序执行到某个位置(某一行代码)时停止运行,我们可以通过在此处位置设置一个断点来实现。当程序执行到断点的位置时,会停止运行。这时,我们可以对进程进行调试,比如打印当前进程的堆栈信息或者打印变量的值等。如下图所示:断点原理 要说明断点的原理,我们首先需要了解下什么是中断。本公众号以前也写过很多关于中断的文章,例如:《一文看懂|Linux中断处理》。想深入了解中断原理的,可以看看上文。下面简单介绍一下什么是中断:中断是为了解决外部设备完成某些工作后通知CPU的一种机制(譬如硬盘完成读写操作后通过中断告知CPU已经完成)。 从物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,处理器会通知OS已经产生中断。这样,OS就可以对这个中断进行

  • Descheduler 实现 K8S Pod 二次调度

    前言Kubernetes中的调度是将待处理的pod绑定到节点的过程,由Kubernetes的一个名为kube-scheduler的组件执行。调度程序的决定,无论是否可以或不能调度容器,都由其可配置策略指导,该策略包括一组规则,称为谓词和优先级。调度程序的决定受到其在第一次调度时出现新pod时的Kubernetes集群视图的影响。由于Kubernetes集群非常动态且状态随时间而变化,因此可能需要将已经运行的pod重新调试到其它节点上,已达到节点使用资源平衡。kube-scheduler简介kube-scheduler是Kubernetes集群的默认调度器,并且是集群控制面的一部分。对每一个新创建的Pod或者是未被调度的Pod,kube-scheduler会选择一个最优的Node去运行这个Pod。然而,Pod内的每一个容器对资源都有不同的需求,而且Pod本身也有不同的资源需求。因此,Pod在被调度到Node上之前,根据这些特定的资源调度需求,需要对集群中的Node进行一次过滤。在一个集群中,满足一个Pod调度请求的所有Node称之为可调度节点。如果没有任何一个Node能满足Pod的资源请

  • SQL笔试50题(下)

    正文共:4832字22图预计阅读时间:13分钟本文目录:5.2sql笔试50题后25题 5.SQL面试50题26.查询每门课程被选修的学生数1--此题只使用Score单表也可以 2select 3c.cname, 4count(s.sid)as'选课人数' 5fromScores,Coursec 6wheres.cid=c.cid 7groupbyc.cname复制sql50_2627.查询出只选修了一门课程的全部学生的学号和姓名1--此题可以在第三题基础上增加限制 2--没有这样的学生。 3SELECTa.sid,a.sname, 4count(b.cid)as'选课数' 5FROMStudenta 6leftjoinScoreb 7ona.sid=b.sid 8groupbya.sid,a.sname 9havingcount(b.cid)=1复制28.查询男生、女生人数1SELECT 2ssex, 3count(sid)as'人数' 4FROMStudent 5GROUPBYssex复制29.查询名字中含有"

  • Transformer各层网络结构详解!面试必备!(附代码实现)

    版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/weixin_41510260/article/details/101445016文章目录1.什么是Transformer2.Transformer结构2.1总体结构2.2Encoder层结构2.2.1PositionalEncoding2.2.2Self-Attention2.2.3Multi-HeadedAttention2.2.4Layernormalization2.2.5FeedForwardNeuralNetwork2.3Decoder层结构2.3.1maskedmutil-headattetion2.3.2Output层2.4动态流程图3.Transformer为什么需要进行Multi-headAttention4.Transformer相比于RNN/LSTM,有什么优势?为什么?5.为什么说Transformer可以代替seq2seq?6.代码实现7.参考文献1.什么是Transformer《AttentionIsAllY

  • 冯大辉做了个小程序,竟有人要为它直播吃翔

    小程序体验师:陈小龙 前几天,冯大辉在小道消息发布了自家开发的小程序「见面助手」。这款小程序的诞生,源自于冯大辉的个人需求——想要一个更高效的工具来约见朋友。在冯大辉的安利下,不少粉丝开始尝试使用,并留言给予肯定。但是,也有一位朋友却不看好这个小程序的前景,并在文末留言「上线两周后,日均活跃用户量能过1000」,他就「直播吃翔」..……这……口味就有点重了。有趣的是,冯大辉还特意把这条留言置顶了。所以,那位朋友究竟是不是来骗吃骗喝的呢?现在,知晓程序(微信号zxcx0101)就带大家看一看这款引发「直播吃翔赌局」的小程序,各位不妨来推断一下,最后谁会输,谁会赢?关注「知晓程序」公众号,微信后台回复「0109」,一张图教你玩转小程序。发起见面说实话,约聚会、活动的小程序已出现了不少,比如MINA奖第8期得主「群约助手」。冯大辉做的这款「见面助手」,专注于约见面,无论界面还是功能都非常简洁。只需设置好见面主题、时间、地点这3项必要信息,就可以成功创建见面活动。邀请见面见面创建成功后,接下来就是分享给要约见的朋友了。分享到聊天界面中的缩略图,刚好能完全呈现所有必要的信息,对于受邀者而言非常直

  • When Math meets Android Animation (3)

    当数学遇上动画:讲述ValueAnimator、TypeEvaluator和TimeInterpolator之间的恩恩怨怨(3)上一节我们得到一个重要的结论,借助TimeInterpolator或者TypeEvaluator“单独”来控制动画所产生的动画效果殊途同归!此外,上一节结尾我们还说到,项目AnimationEasingFunctions和项目EaseInterpolator本质上是差不多的,都是定义了一些动画效果对应的函数曲线。前者是将其封装成了TypeEvaluator,后者是将其封装成了Interpolator!这一节我们来研究下这些函数曲线。1缓动函数曲线下图显示了常见的这些函数曲线,到底这些函数曲线都是什么鬼呢?这些函数曲线最早是由RobertPenner提出来用于实现补间动画的"Pennereasingfunctions",这些曲线主要分成10类,包括"BACK","BOUNCE","CIRCULAR","ELASTIC","EXPO","

  • 高并发情景下避免使用SimpleDateFormat

    平时写程序都习惯了使用SimpleDateFormat,当需要创建当前时间的时间戳,直接调用老套方法SimpleDateFormatdf=newSimpleDateFormat("yyyy-MM-dd");复制然后需要创建时间戳的时候,直接调用方法df.format(newDate())复制在单线程工程中,这种方法毫无问题,但是如果在多线程高并发情景中,这种问题就可能会发生问题。因为SimpleDateFormat是线程不安全的,多线程环境下不能用。不然,可能会发生一些跟你预期不一样的结果。 如何解决? 使用ThreadLocal,我自定义了一个线程安全工具类,代码如下:publicclassThreadLocalDateUtil{ privatestaticfinalStringdate_format="yyyy-MM-ddHH:mm:ss"; privatestaticThreadLocal<DateFormat>threadLocal=newThreadLocal<DateFormat>(); publicstat

  • 资源 | Pandas on Ray:仅需改动一行代码,即可让Pandas加速四倍

    选自UCBerkeleyRiseLab作者:DevinPetersohn机器之心编译参与:NurhachuNull、路雪本文中,来自UCBerkeley的DevinPetersohn发布文章介绍了其参与的项目PandasonRay,使用这款工具,无需对代码进行太多改动即可加速Pandas,遇到大型数据集也不怕。作者还对PandasonRay、Pandas进行了对比评估。机器之心对此文进行了编译介绍。项目链接:https://github.com/ray-project/ray最近,我和一位使用100多TB生物数据的朋友讨论了数据科学库的一些局限性。当面临这种规模的数据时,Pandas成了最受喜爱的工具;然而,当你开始处理TB级别的基因数据时,单核运行的Pandas就会变得捉襟见肘。如果我们拥有更多的处理器核,或者要打开数十TB规模的文件时,我们希望Pandas运行得更快。目前,ApacheSpark是最高性能的分布式选择了,但是如果未对Pandas代码做出足够多的修改,你无法使用ApacheSpark运行Pandas代码。大规模数据科学任务向来都是丢给分布式计算专家来做的,或者至少是熟

  • 手机网页用Bootstrap还是jQuery Mobile

    很多新手纠结这个问题?两个框架都能够支持做手机网页,那么它们的区别是什么呢,适用场景是什么呢?下面我们从这几个方面比较这两个框架:解决问题、功能、适用场景。 解决问题 Bootstrap是一个css框架,针对解决的问题有: 跨设备的网页响应式布局问题。随着手机、平板、各分辨率屏幕的出现,如何能够一套前端在所有设备上自由适应? 多人合作的前端布局和样式的规范问题 常用前端css组件,如按钮、连接、表单、表格、分页组件、下拉菜单、导航栏、ICON等等 常用JS前端组件(需要扩展js支持),如表单验证、Tips、Popup等等 jQueryMobile是移动前端框架,包含js、html、css,提供一套完整的移动前端开发组件,可以比喻成Android开发框架,尽可能提供移动APP所具有的所有功能,针对解决的问题有: 移动网页APP所常用的组件,例如:手机导航栏、选项卡、底部菜单、列表、表单等各种组件,而这些与Bootstrap提供的组件有很大区别,jQueryMobile提供的是类似手机APP的组件,只用于移动网页,而Bootstrap提供的是面向所有设备的组件,并没有对移

  • 实用的Scala泛函编程

       既然谈到实用编程,就应该不单止了解试试一个新的编程语言那么简单了,最好通过实际的开发项目实例来演示如何编程。心目中已经有了一些设想;想用Scala泛函编程搞一个开源的数据平台应用系统,也就是在云平台PaaS层对上一层后台的数据应用平台。想想当电子商务和云应用真正普及后将会出现一大批没有云应用软件开发能力的用户。将来真正的云服务提供商,单提供虚拟机租赁服务是远不足够的,如果能提供一个具备计算资源自动扩展收缩、支持多种数据库以及一套简单的后台系统配置脚本语言(DSL:DomainSpecificLanguage)的后台数据应用平台就能真正满足这些新用户对电子商务系统开发的需求。他们不需要掌握高深的分布式云应用软件开发技术,只要通过系统配置脚本语言就可以按所租赁虚拟机数量配置分布计算任务以及对各种数据库进行存取操作了。后台系统配置脚本语言DSL隐蔽了复杂的后台运行体系,用户面对的是抽象到WebService层后面的一个应用层。这样他们可以沿用习惯的前台网页开发技术实现整个云应用软件系统的开发、实施。上面所提到的所谓开源项目是指在一定时间条件成熟后能有业内有共识的朋友一同参与到整个项目的

  • 如何购买服务器

    首先注册腾讯云账号,注册之后实名认证(个人实名认证适用于年满18周岁的用户)实名认证之后,进入首页,导航栏中产品,然后点图中框12其中一个均可云服务器和轻量应用服务器区别:云服务器:云服务器(CloudVirtualMachine,CVM)提供安全可靠的弹性计算服务。您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用CVM可以极大降低您的软硬件采购成本,简化IT运维工作。轻量应用服务器:轻量应用服务器(TencentCloudLighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、APP、电商应用、云盘/图床和各类开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以套餐形式整体售卖基础云资源并提供高带宽流量包,将热门开源软件融合打包实现一键构建应用,提供极简上云体验。云服务器购买界面:看配置购买,若不懂可咨询客服轻量应用服务器购买界面:看配置购买,若不懂可咨询客服国内服务器和国外服务器区别:国内:需备案除中国香港国外:不需要备案注意事项:个人备案不得涉及经营性

  • 腾讯云腾讯电子签请求结构调用方式

    1.服务地址API支持就近地域接入,本产品就近地域接入域名为ess.tencentcloudapi.com,也支持指定地域域名访问,例如广州地域的域名为ess.ap-guangzhou.tencentcloudapi.com。 推荐使用就近地域接入域名。根据调用接口时客户端所在位置,会自动解析到最近的某个具体地域的服务器。例如在广州发起请求,会自动解析到广州的服务器,效果和指定ess.ap-guangzhou.tencentcloudapi.com是一致的。 注意:对时延敏感的业务,建议指定带地域的域名。 注意:域名是API的接入点,并不代表产品或者接口实际提供服务的地域。产品支持的地域列表请在调用方式/公共参数文档中查阅,接口支持的地域请在接口文档输入参数中查阅。 目前支持的域名列表为: 接入地域 域名 就近地域接入(推荐,只支持非金融区) ess.tencentcloudapi.com 华南地区(广州) ess.ap-guangzhou.tencentcloudapi.com 华东地区(上海) ess.ap-shanghai.tencentcloudapi.co

  • 腾讯云消息队列CKafkaCKafka版本选择建议

    本文为您介绍腾讯云CKafka和社区版Kafka的兼容性,帮助您在使用腾讯云CKafka时根据业务需求选择更加适合您的版本。 概述社区版Kafka目前共演进了0.7.x到2.8.x大概20个版本,从消息队列的角度可分为三个阶段:0.x、1.x、2.x。目前腾讯云针对这三个社区发展阶段提供了四个对应版本:0.10、1.1、2.4、2.8,基本覆盖了用户使用的主流Kafka版本。 其中1.x和2.x这两个大版本主要是对KafkaStreams的优化和改进,在消息引擎方面并未引入太多的重大功能特性(2.x在事务特性方面有较大改进)。KafkaStreams在2.x版本有较大改进,如果您是这些特性的用户,请至少选择2.x的版本。 兼容性说明腾讯云CKafka完美兼容社区Kafka,其中高版本和低版本是完全向下兼容的。例如:自建0.10版本的Kafka,在云上选择0.10、1.1.1、2.4.1版本的CKafka均可;如果自建是高版本,不建议选择低版本(因为不确定业务是否使用高版本携带的特性)。 以下是兼容性说明: CKafka版本 可兼容社区版本 兼容性 0.10.2 ≤0.10.

  • php解决浮点数计算函数bc函数不四舍五入问题(转)

    原文:https://blog.csdn.net/qq_29309533/article/details/114322351 PHP浮点数计算函数不四舍五入 之前做统计模块时,遇到PHP计算精度的问题,比如: $a=2586; $b=2585.98; var_dump(a-b); //期望的结果是: float(0.02) //实际结果: float(0.019999999999982) 复制 之后统一换成加bcadd()、减bcsub()、乘bcmul()、除bcdiv()等计算方法,然后又发现第三个参数的保留小数位数是直接截取,不进行四舍五入,比如: $a=1186; $b=865; $ab=2051; //两个值相加结果是2051 //然后我们来计算百分比 a_rate=bcdiv(a,$ab,3); b_rate=bcdiv(b,$ab,3); //$a_rate=0.578 //$b_rate=0.421 复制 很明显0.578跟0.421相加不等于1,所以还得对浮点数计算的函数进行修改 /** *修改bcadd方法,避免直接截取小数位不四舍五入的问题 *@para

  • kafka的认识、安装与配置

    认识Kafka 花费越少的精力在数据移动上,就能越专注于核心业务---《Kafka:TheDefinitiveGuide》 认识Kafka之前,先了解一下发布与订阅消息系统:消息的发送者不会直接把消息发送给接收者、发送者以某种方式对消息进行分类,接收者订阅它们,以便能接受特定类型的消息。发布与订阅系统一般会有一个broker(n.经纪人、中间商)也就是发布消息的中心点。 Kafka是一款基于发布与订阅的消息系统,一般被称为“分布式提交日志”或者“分布式流平台”。Kafka的数据单元被称作消息,可以看作是数据库中的一行数据,消息是由字节数组组成,故对kafka来说消息没有特别的意义,消息可以有一个可选的元数据,也就是键。键也是一个字节数组,同样对于kafka没有什么特殊意义。键可以用来将消息以一种可控的方式写入分区。最简单的例子就是为键生成一个一致性散列值,然后使用散列值对主题分区数进行取模,为消息选择分区。这样可以保证具有相同键的消息总是被写在相同的分区上。保证消息在一个主题中顺序读取。 为了提高效率,消息将被分批次写入Kafka。批次就是一组消息,类似于redis中的流水线(Pipe

  • 递归测试

    /****@Title:根据税务机关代码单户提取同步申报业务数据*@Description:TODO*@paramswjgDm税务机关代码*/publicvoidzzsybnsrqchdxxtq(StringswjgDm){ //存放传入的税务机关下所有下属税务机关代码,包括其自身List<String>swjgDmList=newArrayList<String>();  getSubSwjgs(v.getSwjgDm(),swjgDmList);} //遍历税务机关列表,提取和同步对应机关下用户的申报业务数据ResultVosbVo=null;for(Stringswjg:swjgDmList){sbVo=sbywsjtqService.zzsybnsrqchdxxtq(swjg);if(!sbVo.isSuccess()){log.error("税务机关代码为["+swjg+"]的税务机关,在同步该税务机关下的申报业务数据时失败:"+sbVo.getMessage());}}} /****@Title:递归获取某个税务机关的下属税务机关*@Des

  • 【深入理解javascript】执行上下文

    参考原文:执行上下文 1、每一个执行上下文,工作分为三个阶段: 准备阶段–>执行阶段–>调用阶段 准备阶段:代码执行之前,设置数据,相当于初始化。 执行阶段:开始执行每一行代码。 调用阶段:可能没有。如果有函数调用,产生新的执行上下文。函数每被调用一次,都会产生一个新的执行上下文环境。 2、代码段 javascript在执行一个代码段之前,都会进行“准备工作”来生成执行上下文。这个“代码段”其实分三种情况——全局代码,函数体,eval代码。 全局代码是一种,这个应该没有非议,本来就是手写文本到<script>标签里面的。 eval代码接收的也是一段文本形式的代码。(eval不常用,也不推荐大家用) 函数体是代码段是因为函数在创建时,本质上是newFunction(…)得来的,其中需要传入一个文本形式的参数作为函数体。 3、准备工作 准备工作阶段,全局代码的上下文环境数据内容为: 普通变量(包括函数表达式),   如:vara=10; 声明(默认赋值为undefined) 函数声明,   如:functionfn(){

  • STM32外部中断小结

    外部中断 在STM32中,每个IO脚都可以作为外部中断的输入脚。 但是一个饮片不可能配置相同数量的中断线,来接收IO的状态(上升,下拉,速度等),所以,怎么使中断线和大数量的IO脚进行配对呢?       如上图所示的中断线配置相对应的IO脚,中断线的数量将大幅度的减少。   外部中断的一般配置方法 1、既然是对IO脚线配置,那IO脚的时钟是第一个需要配置的。 __HAL_RCC_GPIOA_CLK_ENABLE();//开启GPIOA时钟 __HAL_RCC_GPIOC_CLK_ENABLE();//开启GPIOC时钟 __HAL_RCC_GPIOH_CLK_ENABLE();//开启GPIOH时钟复制   2、配置好IO脚的时钟之后,接着是需要配置IO脚的状态。(上升,下拉,速度等) 是配置IO脚的状态,需要用到 HAL_GPIO_Init(GPIOA,&GPIO_Initure);这个函数   GPIO_Initure.Pin=GPIO_PIN_0;//PA0 GPIO_Initure.Mo

  • Android流量统计TrafficStats类的使用

    对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析。android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为long型,如果返回等于-1代表UNSUPPORTED当前设备不支持统计。 Java代码  staticlong getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi  staticlong getMobileRxPackets() //获取Mobile连接收到的数据包总数  staticlong getMobileTxBytes() //Mobile发送的总字节数  staticlong getMobileTxPackets() //Mobile发送的总数据包数  staticlong getTotalRxBytes()&n

相关推荐

推荐阅读