Flutter Dart

[TOC]

语法:

关键字

external 将方法的声明和实现分离 @patch(补丁),好处是可以针对不同的平台做实现。

变量声明:1. 明确声明 2. 类型推导

main(List<String> args) {
  // 1. 明确的变量声明
  String name = "fan";

  // 2. 类型推导(var/final/const)
  // 2.1 var 声明变量
  var age = 29;
  age = 30;
  // 2.2 final 声明常量
  final forever = "永恒";
  // 2.3 const 声明常量
  const jingtai = "静态";

  // 2.4 final const 的区别
  // const必须赋值 常量值(编译期间需要有一个确定的值
  // final可以通过计算、函数获取一个值(运行期间确定一个值

  // const date1 = DateTime.now(); x
  final date1 = DateTime.now();

  // final p1 = Person('fan');
  // final p2 = Person('fan');
  // print(identical(p1, p2)); // 判断 p1 != p2

  // 希望相同的参数看做同一个对象,严格来说不算 单例模式
  const p1 = Person('fan'); // ==>  const p1 = const Person('fan');
  const p2 = Person('fan');
  const p3 = Person('jin');
  print(identical(p1, p2));
  print(identical(p3, p2));
}

数据类型

// Object 和dynamic

// dynamic 是明确声明,和var不一样

// Object调用方法时,编译时会报错

// dynamic调用方法时,编译时不会报错,但是运行时存在安全隐患

非零即真

在js中1或任何非null对象的值被视为true

在dart中,只有bool值为true被视为true

字符串

var str1 = '单引号';
  var str2 = "双引号";
  var str3 = """
  模板
  字符串
  """;

  // 字符串和表达式进行拼接,和ES6一样
  var name = "fan";
  var age = 19;
  var height = 1.88;

// 强调:${变量} 那么{} 可以省略
  var message1 = "my name is ${name}, $age, $height";
  var message2 = "my name is ${name}, ${name.runtimeType}";

集合类型

  // 1. 列表 数组 list
  // 2. 集合 set
  // 3. 映射 对象 字典 map

  var names = ["1", "2", "3"];
  var movies = {"星际穿越", "xiyou", "道明空间"};
  var info = {"name": "fan", "age": 18}; // key 必须可hash

可选值 null 检查最佳实践

bool isConnected(a,b){
	bool outConn=outgoing[a]?.contains(b) ?? false;
	bool inConn = incoming[a]?.contains(b) ?? false;
	return outConn || inConn;
}

?.运算符在左边为null的情况下会阻断右边的调用,?? 运算符主要作用是在左侧表达式为null时为其设置默认值。

对于表达式:

outgoing[a]?.contains(b)

如果outgoing为null 或 outgoing[a]为null或contains(b)的值为null,都会导致表达式为null

function 函数是一等公民

面向对象语言中,对象是一等公民。一等公民可以做参数,返回值,传递。

JS
function demo(){}
Dart
demo(){}

// 必选参数
// 可选参数:1. 位置可选,2. 命名可选
// 位置可选参数:[int age,double height]
// 实参和形参在进行匹配时,是根据位置的匹配
// 注意 ,只有可选参数可以有默认值
void sayHello1(String name) {
  print(name);
}

//位置可选参数
void sayHello2(String name, [int age, double height]) {
  print(name);
}

// 命名可选参数
void sayHello3(String name, {int age, double height = 0}) {
  print(name);
}
//三种函数传入方式
 // 1. 直接传方法名,对函数没有任何限制(参数,返回值)
  test(bar);
//2.  匿名函数 (参数列表){函数体}
  test(() {
    print("匿名函数被调用");
  });

  //3.  箭头函数:条件,函数体只有一行代码
  test(() => print("箭头函数被调用"));

运算符

 // 赋值操作 ??= 当变量有值时,??= 不执行
// 变量为null,将值赋值给变量
  var name = "fan";
  name ??= "jin";
  print(name);

// ??
// 前面变量有值,使用变量的值
// 前面变量无值,返回?? 后边的值。可以理解为三目运算符的简写
  var temp = name ?? "is";
  print(temp);

  // 级联运算符
  var p = Person()
    ..name = "ming"
    ..eat()
    ..run();

流程控制

异步编程

future == promise

JS中Promise对象表示异步操作的最终完成(或失败)及其结果值,Dart中使用Future来表示异步操作。

import 'dart:convert';
import 'dart:html';

main(List<String> args) {
  _getIPAddress() {
    final url = "https://httpbin.org/ip";
    Future<HttpRequest> request = HttpRequest.request(url);
    request.then((value) {
      print(jsonDecode(value.responseText)['origin']);
    }).catchError((error) => print(error));
  }

  _getIPAddress();
}

async 和 await

单继承,使用混合方式实现多继承mixin


// 如果用const 修饰 构造器,类也必须用 final修饰
class Person {
  final String name;

  const Person(this.name);
}
class Person {
  final String name;
  final int age;

// 源自C++中的初始化列表
// 如下常用方式
// 这种初始化方法可以使用表达式
// 另外一种命名可选参数的初始化方式只能使用直接赋值
  Person(this.name, {int age}) : this.age = age ?? 10 {}
  // Person(this.name,{int age = 10})
}
class Person1 {
  String name;
  int age;
  // 同名方法为构造函数
  Person(int age, String name) {
    this.age = age;
    this.name = name;
  }
  
  void sayHello() {
    print("my name is $name");
  }
}

class Eat {
  void eat() {
    print("eat");
  }
}

class Sleep {
  void sleep() {
    print("sleeep");
  }
}

// 抽象类 不能被实例化,通常用于架构师来设计编码格式
abstract class Animal {
  void run(); // 抽象方法
  // 抽象类的用处:我有一个想法,但是不知道怎么实现,提醒继承者去实现
}

// 多继承 混合
class Person2 extends Animal with Eat, Sleep {
  String name;
  int age;
  // 同名方法为构造函数
  Person2(int age, String name) {
    this.age = age;
    this.name = name;
  }

  void sayHello() {
    print("my name is $name");
  }

  @override
  void run() {
    print("haha run");
  }
}

混合的菱形继承问题:编译后,最近原则调用方法。先找自身的,再找with后面,从后往前以此调用。

多核CPU的利用

Isolate概念 隔离 Dart是单线程的,线程所在的空间被称为Isolate。比如Flutter中有一个Root Isolate,负责运行Flutter代码,例如UI渲染,用户交互等。 在Isolate中,资源隔离做的非常好,每个Isolate有自己的Event Loop和Queue。