dart快速学习记录

577 阅读4分钟

变量

  • var声明变量;
  • late 声明将来不为空的延时变量;
  • final const 声明不可变变量;
  • const 编译时常量,可以用其他const变量为其赋值;

内置类型

  • Numbers: init, double
  • Strings String
  • Booleans bool
  • Lists (arrays)
  • Sets (Set)
  • Maps (Map)
  • Runes (常用语在Characters API中进行字符替换)
  • Symbols (Symbol)
  • null (Null)

字符转数字

var one = int.parse('1')
var one = double.parse('1.1')

数字转字符

String one = 1.toString()
String two = 1.131415.toStringAsFixed(2);
var s = 'string as'
'${s}' 可以省略为 '$s'

拼接字符串方式 多行 或者 +

var a = '123' + '456'
var a = '123'
        '456';

三个单引号,三个双引号可以创建多行

var s1 = '''
asdads
asdasdas
''';

在字符串前加r可以输出不转义的字符串

var s =  r'asd \n adasd '

Lists 集合

集合中if,集合中for

var nav = [  'home',  'fruint',  if(true) 'out']

var listArr = [1,2,3]
var listfor = [  '#0',  for(var i in listArr) '$i']

Sets

特定元素的无序集合

var sets = {'aaa','bbb','ccc'};
sets.add('ddd')
sets.length

Maps

var gifts = {
  'first': 'partridge',
  'second': 'asdadsa ',
  'third': 'asdasd e1 '
}

Runes

  • 表示Unicode字符:\uXXXX, XXXX为四位数的16进制数字:心形字符(♥)的 Unicode 为 \u2665
  • 不是四位数的16进制数字,需要使用大括号括起来,大笑的 emoji 表情(😆)的 Unicode 为 \u{1f600}

函数

bool isEqual(int a, int b){
  return a == b
}

bool isEqual(int a, int b) => a == b

参数

  • 必要参数 在数定义在参数列表前面
  • 可选参数 定义在必要参数后面
  • 可选参数 可以是 命名参数 或者 位置的

命名参数

默认是可选参数,除非被标记为required

定义函数

void func({bool? bold, bool? hidden})

调用

func(bold: true, hidden: false)

命名参数也使用required标识

void func({bool? bold, required bool? hidden})

可选位置参数

void func(bool a, bool b, [String? c]){
    if(c != null) return c;
}

默认参数值

可以为命名参数和位置参数设置默认值,没有默认值的时候默认为null

void func({bool a = true}){...}

位置参数设置默认值

void say(String from, String msg, [String device = 'device name']){
    return '$from says $msg with a $device'
}

main()函数

程序入口

匿名函数,变量作用域,闭包等和js类似

返回值默认为null

运算符

大致与js相似

类型判断运算符

  • as 类型转换
(employee as Person).firstName = 'Bob';
// employee 为 null 会抛出异常
  • is 类型判断
if(employee is Person){
    employee.firstName = 'Bob'
}
// employee 为 null 不会抛出异常
  • is! 与is 相反 相当于 is not

赋值运算符

b ??= value
// 如果b是null,则赋值value,如果b不为null,则保持不变

条件表达式

  • 三元表达式 与js一样
  • ??用法
a ?? b
// a 不为 null 结果为 a
// a 为 null 结果为 b

级联运算符

连续调用 ..

// 例子
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;
// 级联用法
var paint = Paint()
  ..color = Colors.black
  ..strokeCap = StrokeCap.round
  ..strokeWidth = 5.0;

?..

如果为空则不执行后续

querySelector('#confirm') // Get an object.
  ?..text = 'Confirm' // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

流程控制

与js一致

  • if(){}else{}
  • for(){}
  • for(var a in arr){}
  • arr.forEach()
  • while(true){}
  • do{}while()
  • break continue
  • switch case break continue (每个case都有局部变量)

断言

条件为false时,可以打断代码执行

assert(txt != null)

异常

抛出异常

throw 可以抛出任意异常对象 优秀的代码通常会抛出 Error 或 Exception 类型的异常。

捕获异常

  • on可以指定异常类型
  • catch可以捕获异常对象
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}
  • rethrow 可以降异常再次抛出
  • finally始终执行
try{
    ...
}finally{
    ...
}

构造函数

var p1 = Point(2,2);

常量构造函数,创建编译时常量

var p = const ImmutablePoint(2,2)

Object.runtimeType用来获取对象类型

实现构造函数

class Point{
    double x = 0;
    double y = 0;
    // 用参数赋值
    Point(double x, double y){
        this.x = x;
        this.y = y;
    }
    // 语法糖
    Point(this.x, this.y);
}

子类调用父类时候

1 子类初始化列表
2 调用父类的匿名无参数构造函数 3 子类的constructor

如果父类没有匿名无参数构造函数,则子类必须调用父类的一个构造函数用:指定

class Children extends Person{
    Children() : super.fromJson(...);
}

抽象

abstract 抽象方法,抽象类 定义不实现

隐式接口

只想调用方法但是不想继承的时候 implements

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final String _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

  // In the interface.
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// An implementation of the Person interface.
class Impostor implements Person {
  String get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

实现多个类接口

class Point implements Comparable, Location {...}

重写类成员

class SmartTelevision extends Television {
  @override
  void turnOn() {...}
  // ···
}

noSuchMethod 如果调用了不存在的方法或者变量会触发,可以重写来做出响应

class A {
  // Unless you override noSuchMethod, using a
  // non-existent member results in a NoSuchMethodError.
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: '
        '${invocation.memberName}');
  }
}

枚举

enum Color {red, green, blue}

assert(Color.red.index == 0)

获取全部枚举值

List<Color> colors = Color.values;
assert(colors[2] == Color.blue);

静态类和静态方法 static

静态方法不能使用this,但是可以访问静态变量

import 'dart:math';

class Point {
  double x, y;
  Point(this.x, this.y);

  static double distanceBetween(Point a, Point b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
  }
}

void main() {
  var a = Point(2, 2);
  var b = Point(4, 4);
  var distance = Point.distanceBetween(a, b);
  assert(2.8 < distance && distance < 2.9);
  print(distance);
}

import 'dart:html'
import 'package: src/test.dart'
import 'package: src/test.dart' as lib2;

导入一部分

import 'package:lib1/lib1.dart' show foo;
import 'package:lib1/lib1.dart' hide foo;

懒加载

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

Future<void> greet() async{
    await hello.loadLibrary();
    hello.printGreeting();
}

创建包

image.png

主 Library 文件 shelf.dart 在 lib 目录下,通过 shelf.dart 文件导出 lib/src 目录下的若干文件。为了不导出过多的 API,并且为开发者提供公开的 API 的概览, shelf.dart 使用了 show 来指定哪些内容需要导出:

export 'src/cascade.dart' show Cascade;
export 'src/handler.dart' show Handler;
export 'src/hijack_exception.dart' show HijackException;
export 'src/middleware.dart' show Middleware, createMiddleware;
export 'src/middleware/add_chunked_encoding.dart' show addChunkedEncoding;
export 'src/middleware/logger.dart' show logRequests;
export 'src/middleware_extensions.dart' show MiddlewareExtensions;
export 'src/pipeline.dart' show Pipeline;
export 'src/request.dart' show Request;
export 'src/response.dart' show Response;
export 'src/server.dart' show Server;
export 'src/server_handler.dart' show ServerHandler;

条件导入

export 'src/hw_none.dart' // Stub implementation
    if (dart.library.io) 'src/hw_io.dart' // dart:io implementation
    if (dart.library.html) 'src/hw_html.dart'; // dart:html implementation

该代码的作用如下:

  • 在一个可以使用 dart:io 的 app 中(例如一个命令行应用),导出 src/hw_io.dart
  • 在一个 web 应用中可以使用 dart:html 导出 src/hw_html.dart
  • 若是其他情况,则导出 src/hw_none.dart

要条件导入一个文件可以使用和上面一样的方式,仅需将 export 改为 import 即可。 所有条件导出的库必须实现相同的 API。下面是 dart:io 实现的一个例子

异步

与js类似

Future<void> checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

main函数也可以使用

Future<void> main() async {
  // ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  // ...
}

生成器

同步生成器,返回Iterable对象

Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}

异步生成器,返回Stream对象

Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}

递归调用,可以使用yield*提升性能

terable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}

类型别名

typedef IntList = List<int>;
IntList il = [1, 2, 3];
typedef ListMapper<X> = Map<X, List<X>>;
Map<String, List<String>> m1 = {}; // Verbose.
ListMapper<String> m2 = {}; // Same thing but shorter and clearer.

文档注释

/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
///
/// Just like any other animal, llamas need to eat,
/// so don't forget to [feed] them some [Food].
class Llama {
  String? name;

  /// Feeds your llama [food].
  ///
  /// The typical llama eats one bale of hay per week.
  void feed(Food food) {
    // ...
  }

  /// Exercises your llama with an [activity] for
  /// [timeLimit] minutes.
  void exercise(Activity activity, int timeLimit) {
    // ...
  }
}