Dart | 基础学习笔记

基本数据类型

Number

  • int

    • int a = 1;
    • int b = 0xDEFFFF;
  • double

    • double x = 1.0;
  • 转换

    • var a = int.parse('1');
    • var b = double.parse('2.5');
    • 指定进制:
      var hex = int.parse('10', radix: 16);
    • String a = 1.toString();
    • String b = 3.1415.toStringFixed(2);
      b = '3.14'

String

  • var a = 'this is a string text';
  • var b = '''
    this is a multiple line string
    text....
    ''';

Boolean

  • bool a = true;
  • bool b = 1 > 0;

List

  • var a = [1, 2, 3];
  • List<String> = ['a', 'b'];
  • [1,2,3].sort((a,b) => a.compareTo(b));

Set

  • var a = {'a', 'b'};
  • .length
  • .add()
  • .addAll(aSet)

Map

  • var aMap = Map();
  • var aMap = {};
  • Map<String, dynamic> map = {
    'a': 1,
    'b': 'hello',
    'c': ()=>print('hello')
    };
    map.forEach((key, val){
    print('key:val');
    });
  • Map<int, String> b = {0: 'a', 1: 'b'};

Rune

  • UTF-32编码字符
  • (♥) 是 \u2665
  • (�) 是 \u{1f600} -- 非4个字符的用{}包裹

函数

Function类

  • int aFunc(int a, int b) => a+b;
  • void aFunc(){}
  • aFunc(){}
  • 用{}指定命名参数
    aFunc(title: String, {Key key, @required Widget child})
  • 用[]指定可选参数
    aFunc(title: String, {Key key, @required Widget child})
  • 设置默认参数值
    aFunc(title: 'hello', {Key key, @required Widget child})
  • 匿名函数(lambda/closure):(){}
  • 函数返回类型
    Function makeAdder(num addBy) {
    return (num i) => addBy + i;
    }

运算符

算数

  • ~/
    除数取整:5 ~/ 2 = 2
  • %
    除数取余:5 % 2 = 1

类型判定

  • as:将对象强制转换为特定类型
    (emp as Person).firstName = 'Bob';
  • is:判定对象是否是指定的类型
    obj is Object;
    is!:是上面的取反

赋值运算符

  • ??=
    b ??= 'a'; (如果b为null,则b='a',否则不变)

条件表达式

  • ? :
    a = b>0 ? 'yes' : 'no';
  • ??
    a = b ?? 'a'; (如果b为null,则a='a',否则a=b)

级联运算符

  • .. :对同一个对像进行一系列的操作

querySelector('#confirm') // 获取对象。
..text = 'Confirm' // 调用成员变量。
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));

上面代码等同于:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

  • 严格的来讲, “两个点” 的级联语法不是一个运算符。 它只是一个 Dart 的特殊语法。

可选类型(类似swift的Optional)

  • ?.
    a = obj?.name; (如果obj为null,则a=null;
    如果obj.name为null,a=null)

控制流程语句

if-else

for

  • for(var i=0; i<5; i++){}

  • forEach

    • [1,2,3].forEach((val) => print('val: $val'));
  • for-in

    • (for var i in [1,2,3]){}

switch-case

  • var word = 'a';
    switch(word){
    case 'b':
    print('hello b');
    break;
    default: break;
    }

assert

  • assert(text != null);
  • assert 语句只在开发环境中有效, 在生产环境是无效的;

枚举

enum Color {

red, green, blue
}

Color.red.index == 0;

Color.values[0] == Color.red;

异常

try-catch

  • try{
    doingSomething();
    } on Exception catch(e) {
    print('明确类型的异常');
    } catch(e, s){
    print('不明确的异常:e, 堆栈:s');
    }

rethrow

finally

  • try{
    } finally {
    }
  • try{
    } catch(e) {
    } finally {
    }

Dart 是一种基于类和 mixin 继承机制的面向对象的语言。

继承用extends关键字;
实现多个接口(抽象类)用implements关键字;
重写父类方法用@override关键字;

获取对象的类型

  • Type aType = a.runtimeType;

实例变量

  • class Point {
    int x; // 声明实例变量 x,初始值为 null 。
    int y; // 声明实例变量 y,初始值为 null 。
    double z = 0; // 声明示例变量 z,初始值为 0 。
    }
  • 所有未初始化的实例变量默认值都为 “null” ,而不是int的为0
  • 隐式生成setter和getter方法

构造函数

  • 默认构造函数

    • var p = Person();
      var p = new Person(); (new是可选的)
  • 自定义构造函数

    • Person(int age, String name){
      this.age = age;
      this.name = name;
      }
      this指代当前实例对象,跟oc中的self一样。
      上面的代码等同于:
      Person(this.age, this.name);
    1. 子类不会继承父类的构造函数。 子类不声明构造函数,那么它就只有默认构造函数 (匿名,没有参数)。
  1. 如果希望使用父类中定义的命名构造函数创建子类, 就必须在子类中实现该构造函数。
  2. 默认情况下,子类的构造函数会自动调用父类的默认构造函数
  • 命名构造函数

    • 指定意图的构造函数:
      Point.origin() {
      x = 0;
      y = 0;
      }
  • 父类构造函数

    • class Person {
      String firstName;

    Person.fromJson(Map data) {
    print('in Person');
    }
    }

class Employee extends Person {
// Person does not have a default constructor;
// you must call super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}

main() {
var emp = new Employee.fromJson({});

// Prints:
// in Person
// in Employee
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';
}
- // 在构造函数体执行之前,
// 通过初始列表设置实例变量。
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): (x,y)');
}

  • 工厂构造函数

    • 一个工厂构造函数可能会返回一个 cache 中的实例, 或者可能返回一个子类的实例。
    • class Logger {
      final String name;
      bool mute = false;

    // 从命名的 _ 可以知,
    // _cache 是私有属性。
    static final Map<String, Logger> _cache =
    <String, Logger>{};

    factory Logger(String name) {
    if (_cache.containsKey(name)) {
    return _cache[name];
    } else {
    final logger = Logger._internal(name);
    _cache[name] = logger;
    return logger;
    }
    }

    Logger._internal(this.name);

    void log(String msg) {
    if (!mute) print(msg);
    }
    }

  • getters & setter

    • class Rectangle {
      num left, top, width, height;

    Rectangle(this.left, this.top, this.width, this.height);

    // 定义两个计算属性: right 和 bottom。
    num get right => left + width;
    set right(num value) => left = value - width;
    num get bottom => top + height;
    set bottom(num value) => top = value - height;
    }

void main() {
var rect = Rectangle(3, 4, 20, 15);
assert(rect.left == 3);
rect.right = 12;
assert(rect.left == -8);
}

  • 抽象类

    • 抽象方法只存在于 抽象类 中。
    • abstract class Doer {
      // 定义实例变量和方法 ...

    void doSomething(); // 定义一个抽象方法。
    }

class EffectiveDoer extends Doer {
void doSomething() {
// 提供方法实现,所以这里的方法就不是抽象方法了...
}
}

  • noSuchMethod()

    • 这样可以避免一些dynamic类型的实例对象类型错误,导致访问某些方法时崩溃问题;
      如Person a = null; a.name(崩溃);
    • class A {
      // 如果不重写 noSuchMethod,访问
      // 不存在的实例变量时会导致 NoSuchMethodError 错误。
      @override
      void noSuchMethod(Invocation invocation) {
      print('You tried to use a non-existent member: ' +
      '${invocation.memberName}');
      }
      }
  • Mixin

    • 为类添加功能
      用with关键词,类似于swift的协议
    • class Maestro extends Person
      with Musical, Aggressive, Demented {
      Maestro(String maestroName) {
      name = maestroName;
      canConduct = true;
      }
      }
    • mixin Musical {
      bool canPlayPiano = false;
      bool canCompose = false;
      bool canConduct = false;

    void entertainMe() {
    if (canPlayPiano) {
    print('Playing piano');
    } else if (canConduct) {
    print('Waving hands');
    } else {
    print('Humming to self');
    }
    }
    }

    • 指定类型的mixin
      mixin MusicalPerformer on Musician {
      // ···
      }
  • 静态方法/类方法

    • class Point {
      num x, y;
      Point(this.x, this.y);

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

  • 静态常量

    • class Queue {
      static const initialCapacity = 16;
      // ···
      }

泛型

<T>表示

List<String> list = ['a', 'b'];

var list = <int>[0, 1, 2];
var map = <String, dynamic>{};

限制泛型类型

  • class Foo<T extends SomeBaseClass> {
    // Implementation goes here...
    String toString() => "Instance of 'Foo<$T>'";
    }

class Extender extends SomeBaseClass {...}

泛型函数

  • T aFunc<T>(T param){
    }

import

  • import 'dart:html';
    import 'package:test/test.dart';
  • 前缀
    import 'package:lib1/lib1.dart';
    import 'package:lib2/lib2.dart' as lib2;

// 使用 lib1 中的 Element。
Element element1 = Element();

// 使用 lib2 中的 Element。
lib2.Element element2 = lib2.Element();

  • 导入一部分
    // Import only foo.
    import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;

  • 延迟加载:让应用在需要的时候再加载库
    import 'package:greetings/hello.dart' deferred as hello;

当需要使用的时候,使用库标识符调用 loadLibrary() 函数来加载库:
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
在一个库上你可以多次调用 loadLibrary() 函数。但是该库只是载入一次。

export

library

part

异步

返回Future/Stream

async-await关键字

  • Future checkVersion() async {
    var version = await lookUpVersion();
    // Do something with version
    }
  • await 表达式会阻塞代码的执行,直到需要的对象返回为止。

Isolates

所有 Dart 代码都在隔离区( isolates )内运行,而不是线程。

每个隔离区都有自己的内存堆,确保每个隔离区的状态都不会被其他隔离区访问。

typedef

自定义函数类型

typedef NetworkRequestCompletion = void Function(Error error, Map<String, dynamic> json);

元数据

元数据注释以字符 @ 开头

/// Deprecated: Use [turnOn] instead.

@deprecated
void activate() {
turnOn();
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342