Dart学习-基础

146 阅读2分钟

操作符

  • 一元运算符
    • 前置:expr++、expr—、()、[]、?[]、.、?.
    • 后置:-expr、!expr、~expr、++expr、--expr、await expr
  • 计算:+、-、*、/、%、~/
  • 位移:<<、>>、>>>
  • 按位:&、^、|
  • 判断:>=、>、<=、<、==、!=、as、is、is!
  • 逻辑:&&、||
  • 判断null:??
  • 三元判断:expr1 ? expr2 : expr3
  • cascade:..、?..
  • 赋值:=、*=、%=、>>>=、^=、+=、/=、<<=、&=、|=、-=、~/=、>>=

基础类型

使用var声明的变量会自动推断变量类型。

String:字符串

var a = "aaa";
String b = "bbb";
String c = 'ccc'; // 单引号也可以

Number:数值

var a = 1;
var b = 1.1;
int c = 1;
double d = 1.2;
// 使用num声明的变量可以在int和double之间互相赋值
num e = 1; // 比如e=1.2,也不会保持
num f = 1.2;

[x] Number g = 12; // 没有这种声明方法

Boolean:布尔

var a = true;
bool b = false;

List:列表

var list = [1,2,3]; // 根据初始数据推断具体泛型为List<int>
var stringList = <String>[]; // 带类型的字面量
[x] list.add("a"); // 会抛出异常

List list1 = [4,5,6, "a"]; // 不指定泛型,初始值会混合数据则默认泛型为List<Object>
List<int> list2 = [7,8,9]; // 指定泛型

Set:无序集合

var ids = {1,2,3,4}; // 类似列表,推断类型为Set<int>,无法添加int以外的类型
var ages = <int>{}; // 明确指定类型约束
Set names = {1, "Tom"}; // 使用类型关键字声明,不带类型约束
Set<String> words = {"this", "is"}; // 使用类型关键字声明,带类型约束

Map:映射

// 也可以使用Map<String, String> giftsh或者Map gifts来声明
var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves'
};

var test = Map<Object, String>();
test[gifts] = "gifts";

类型别名

typedef IntList = List<int>;
IntList il = [1, 2, 3];

typedef ListMapper<X> = Map<X, List<X>>;
ListMapper<String> m2 = {};

typedef Compare<T> = int Function(T a, T b)

函数

普通函数

bool isEmpty(List data){
	return data.length == 0;
}
// 无返回函数使用void声明,其中void可以省略
void log(){}
log1(){}

函数参数

// 参数可以不声明类型
log(info){ print(info); }

// 参数声明类型
log(String info){ print(info); }

// 可为空参数
enableFlags(bool? bold, bool? hidden){}

// 可选参数
void log(String info, [String? date, int? id]) {}
void log(String info, [String? date, int? id = 123]) {} // 可选参数带默认值
log("test");
log("test", "date");
log("test", "date", 123);

// 命名参数
enableFlags({bool? bold, bool? hidden}){} // 参数可为空
enableFlags({bool? bold, bool hidden = true}){} // 带默认值
enableFlags({required bool bold, bool hidden = true}){} // bold为必传参数
enableFlags(bold: true, hidden: false);

箭头函数

// 箭头函数没有函数体,只能直接返回结果
var say = (String name) => 'hello, $name';

匿名函数

const list = ['apples', 'bananas', 'oranges'];
list.forEach((item) { print('${list.indexOf(item)}: $item'); });

主函数:程序入口

void main(){}

其他

  • 函数可以作为一等对象
  • 函数可以作为参数传入
  • 函数可以作为结果返回

获取对象的类

var test = Test();
Type t = test.runtimeType;

构造函数

const double xOrigin = 0;
const double yOrigin = 0;

class Point{
	double? x,y;
	
	Point(); // 普通构造函数
	Point(this.x, this.y); // 自动赋值构造函数,且无处理
	Point(this.x, this.y){} // 自动赋值构造函数,且有处理
	Point(this.x, this.y, int z){} // 自动赋值构造函数并带额外参数,且有处理
	Point(Map data) : super.fromJson(data); // 普通构造函数调用父级命名构造函数

	const Point(this.x, this.y); // 常量构造函数,只能赋值给final修饰的属性

	Point.init(); // 普通命名构造函数
	Point.origin() : x = xOrigin,y = yOrigin; // 带赋值的命名构造函数
	Point.origin() : x = xOrigin,y = yOrigin {} // 带赋值的命名构造函数,带处理
	Point.from(double x, double y) : this(x, y); // 命名构造函数调用普通构造函数
	Point.from(double x, double y) : this(x, y){} // 命名构造函数调用普通构造函数,待处理
	// 如果一个类有父类,那么子类的命名构造函数必须跟父类,无法新增
	Point.fromJSON(Map data) : super.fromJSON(data); // 命名构造函数调用父级命名构造函数
	Point.fromJSON(Map data) : super.fromJSON(data){} // 命名构造函数调用父级命名构造函数,带处理
}

运算符重载

class Point {
  final double x, y;

  const Point(this.x, this.y);
	
 	Point operator +(Point p) => Point(x + p.x, y + p.y);
	Point operator -(Point p) => Point(x - p.x, y - p.y);
}
var p1 = Point(1, 1);
var p2 = Point(2, 2);
p1 + p2; // Point{x:3, y:3}
p2 - p1; // Point{x:1, y:1}

对象为函数

class Axis {
  String call(int x, int y) => "x: $x, y: $y";
}
var axis = Axis();
var pos = axis(12, 23);
print(pos); // x: 12, y: 23

异常

抛出异常

throw FormatException('Expected at least 1 section');
throw 'Out of llamas!';

捕获异常

try {
  breedMoreLlamas();
} on OutOfLlamasException { // 捕获指定异常
  buyMoreLlamas();
} on Exception catch (e) { // 捕获指定异常并获得指定信息
  print('Unknown exception: $e');
} catch (e, s) { // 捕获其他所有未指定的异常,并获取异常信息,s为异常栈路径信息
  print('Something really unknown: $e');
	rethrow; // 重新抛出异常
}

异步

主要提供Future和Stream两种异常类型

异步函数

// 使用async声明为异步函数,返回Future对象,泛型为返回数据的类型
Future<void> checkVersion() async {
	await doSomethings(); // await只能在async函数里面使用
}

异步流

Future<void> main() async {
	// 主要使用await for来等待异步流
	await for (final request in requestServer) {
  	handleRequest(request);
	}
}

生成器

同步生成器返回迭代器(terable),异步生成器返回流对象(Stream)

// 同步生成器
Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}
// 异步生成器
Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}

方法扩展

extension <extension name> on <type> {
  (<member definition>)*
}

extension NumberParsing on String {
  int parseInt() {
    return int.parse(this);
  }
  double parseDouble() {
    return double.parse(this);
  }
}

"42".parseInt() // 42

集合的内解析

// 在集合内使用if判断
["bb", if (true) "cc", "dd"] // ["bb", "cc", "dd"]
{"a", if(false) "b"} // {a}
{"a": 1, if(true) "b": 2} // {a: 1, b: 2}

// 在集合内使用for循环
var data = [1,2,3];
[for(var i in data) i] // [1,2,3]
{for(var i in data) i} // {1,2,3}
{for (var i in data) "$i": i} {1: 1, 2: 2, 3: 3}

// for和if可以嵌套使用

导入重命名:相当显示指定命名空间

import 'package:lib2/lib2.dart' as lib2;
lib2.<xxxx>

模块显示与隐藏

// 只导入foo
import 'package:lib1/lib1.dart' show foo;

// 不导入foo
import 'package:lib2/lib2.dart' hide foo;

延迟导入

import 'package:greetings/hello.dart' deferred as hello;

Future<void> greet() async {
  await hello.loadLibrary(); // 需要等待导入成功
  hello.printGreeting();
}