Flutter 入门指北(Part 1)之 Dart

该文已授权公众号 「码个蛋」,转载请指明出处

最近 Flutter 真心火爆到不要不要的,随大流,学一波,在这之前,对于语言的语法还是需要有些必要的了解的,Dart 这门语言,说实话对于会 Java 这类面向对象的语言的小伙伴们来说,真的灰常灰常简单,这边我总结了一些 DartJava 的一些语法差异,当然,只是部分,但是,按照我目前的学习进度来说,了解了这些对于写 Flutter 项目绝对够了。小伙伴也可以自己查看,我这边提供一个自己学习的网址 Dart 快速入门

温馨提示:本篇文章没有图,没有图,没有图,可能会造成部分不适,请注意,请注意,请注意,系好安全带,我们要「开车了」......

1. Variables

Dart 变量类型可以通过具体的赋值进行推导,例如:var name = 'kuky' 则定义了一个 String 类型对象 name,也可以通过指定具体的类型 String name = 'kuky',如果没有初始化变量,则默认值为 null,类型为数字的变量默认值同为 nulljava 不同,javaint 默认为 0.)如果需要定义常量,可以通过 finalconst 进行定义,final 变量只能赋值一次,const 是编译时常量。

2. Build-in-types

Dart 内置类型包括 :

  • Numbers 包括 int[-2^53 ~ 2^53], double[64-bit 浮点数]

  • Strings Dart 字符串是 UTF-16 编码的字符序列, 可以使用单引号或者双引号来创建字符串。

    1. 通过 == 判断两个字符串是否相同
    2. 通过三对单引号'''aaa'''或者双引号"""aaa"""可以创建多行字符串对象
    3. 使用前缀 r 创建 raw string,字符串内不会进行转义,例如:var a = r'haha \n breakLine' 打印 a 对象则会按照输入的输出,不会进行换行
  • Booleans Dart 中,只有 true 对象才被认为是 true, 所有其他的值都是 false

  • Lists 列表,例如:var list = [1, 2, 3, 4]

    ​ 通过 const 关键词可以定义一个不可变列表 var list = const [1, 2, 3, 4]

    ​ 参数化定义var name = <String>['Jone', 'Jack']

  • Maps 键值对,例如:var map = {'one': 1, 'two': 2}

    ​ 如果键值对需要添加新的键值对,直接指定即可,map['three'] = 3,若查找的键不存在,返回 null

    ​ 参数化定义 var map = <String, int>{'one': 1, 'two': 2}

  • Runes 代表字符串的 UTF-32 code points,通常使用 \uXXXX 的方式来表示 Unicode code point, XXXX 是4个 16 进制的数,例如 \u2665 返回心形符号 ()

  • Symbols 代表 Dart 程序中声明的操作符或者标识符,几乎不使用

3. Function

函数方法的可选参数通过在参数列表中用 {} 指定,例如:

void say(String name, {String word = 'hello'}){
    print('$name say $word');
  }

// 通过(可选参数名 + :)进行可选参数的赋值
main(){
    say('kuky', word: 'Hello World'); // kuky say Hello World
}

word 参数为可选参数,默认值为 hello

4. Operators

操作符几乎和别的语言类似,提个比较特殊的赋值操作符 ??=?.操作符

var a = 1;
var b;
b ?? = a; // 如果 b 的值是 null 则将 a 赋值给 b,否则保持不变
var c = size?.x; // 如果 size 为 null 则返回 null,否则返回 size.a 的值
5. Conditional Expressions

Dart 可以通过两个特殊的操作符替换 if(){} else{} 表达式

/// condition? expr1: expr2 同 java 三目运算符
var a = -1;
a = a < 0 ? -1 : a;
/// expr1 ?? expr2 
String toString() => msg ?? super.toString() // 如果 expr1 不为 null 则返回 expr1 否则返回 expr2
6. Cascade Notaion(..)

级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量

class Size{
    double x;
    double y;

  @override
  String toString() {
    return 'Size{x: $x, y: $y}';
  }
}

var size = Size();
/// 通过级联操作符进行赋值,可以更加简洁,!!如果函数返回值为 void 则不能进行级联!!
print(size
      ..x = 10
      ..y = 100
      ..toString()); /// 输出 Size{x: 10.0, y: 100.0}
7. foreach

通过 foreach 循环遍历一个实现 Iterable 接口的对象

var items = [1, 2, 3, 4, 5];
var maps = {'a': 1, 'b': 2};

items.where((i) => i > 2).forEach((i) => print(i));  // 3, 4, 5
maps.forEach((key, value) => print('$key => $value')); // a => 1, b => 2
8. Switch and case

如果需要实现继续到下一个 case 语句中继续执行,则可以 使用 continue 语句跳转到对应的标签处继续执行

var command = 'Close';
switch (command.toLowerCase()) {
  case 'close':
    print('close');
    continue open;
        
  open: // 这是个标签
  case 'open':
    print('open');
    break;
}
9. Assert

如果条件表达式结果不满足需要,则可以使用 assert 语句俩打断代码的执行,例如:assert(a == 1);

10. Exceptions

所有的 Dart 异常是非检查异常。捕捉 exceptions 的时候可以通过 on 指定 exceptions 类型,再使用 catch 捕获

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
} on Exception catch (e) {
  print('Unknown exception: $e');
} catch (e, s) { // 函数 catch 可以带有一个或两个参数,第一个参数为抛出的异常对象,第二个为堆栈信息
  print('Something really unknown: $e');
  print('Stack trace:\n $s');
  rethrow; // 通过 rethrow 可以将异常重新抛出
}
11. Classes

Dart 中的类都是单继承,但是同时支持 mixin 的继承机制(Object 类,每个类都只有一个超类),所有的类都继承于 Object,通过调用 runtimeType 判断实例的类型。每个实例变量都会自动生成一个 getter 方法(隐含的), Non-final 实例变量还会自动生成一个 setter 方法。

  • Constructors

    Dart 的构造函数同 Java 类似

    class Size {
      num x, y;
    
      Size(num nx, num y){
        x = nx;
        this.y = y; // this 关键字只有当名字冲突时候使用,否则 Dart 推荐省略 this
      }
        
      Size(this.x, this.y); // Dart 通过语法糖省略了构造函数的赋值过程,效果同上
    }
    

    如果没有定义构造函数,则会有个默认构造函数。默认构造函数没有参数,并且会调用超类的 没有参数的构造函数。子类不会继承超类的构造函数,子类如果没有定义构造函数,则只有一个默认构造函数。

    Dart 通过命名构造函数为类创建多个构造函数,同时指明意图

    class Size {
      num x, y;
    
      Size(this.x, this.y);
    
      Size.fromJson(Map json){
        this.x = json['x'];
        this.y = json['y'];
      } // 因为构造函数不能继承,如果希望子类也有超类一样的命名构造函数,必须在子类中实现该构造函数
      
      // 构造函数体执行之前除了可以调用超类构造函数之外,还可以初始化实例参数
      // 初始化列表非常适合用来设置 final 变量的值
      Size.fromJsonInit(Map json)
          : this.x = json['x'],
            this.y = json['y'];
    }
    

    常量构造函数(如果类需要提供一个状态不变的对象,通过 const 构造函数实现)

    class ConstPoint {
      final num x;
      final num y;
    
      const ConstPoint(this.x, this.y);
    }
    

    工厂方法构造函数(如果一个类不需要每次都提供一个新的对象,通过 factory 构造函数实现)

    class HttpCore {
      HttpCore._internal();
    
      factory HttpCore() {
        if (_instance == null) _instance = HttpCore._internal();
        return _instance;
      }
    
      static HttpCore _instance;
    
      static HttpCore get instance => HttpCore();
      
      void _request(){
          //...
      }
    }
    
  • 每个类都隐式的定义了一个包含所有实例成员的接口, 并且这个类实现了这个接口,通过抽象类实现类似 Java 接口的功能。

    abstract class Callback {
      void print(String msg);
    }
    
    class A implements Callback{
      @override
      void print(String msg) {
        print(msg);
      }
    }
    
  • Mixins Dart | 什么是Mixin

12. Asynchrony support
  1. Future

    loopIntegers() {
      // 通过 then 进行获取到 Future 对象后的操作
      getListDelay().then((ints) => ints.forEach((i) => print(i)));
    }
    
    // 生成一个 Future 对象
    Future<List<int>> getListDelay() {
      return Future.delayed(Duration(seconds: 2), () => List.generate(10, (delta) => delta));
    }
    

    通过 async await 简化 Future 操作

    runUsingFuture() {
      //...
      findEntrypoint().then((entrypoint) {
        return runExecutable(entrypoint, args);
      }).then(flushThenExit);
    }
    
    // 简化了 then
    runUsingAsyncAwait() async {
      //...
      var entrypoint = await findEntrypoint();
      var exitCode = await runExecutable(entrypoint, args);
      await flushThenExit(exitCode);
    }
    

    有时候要求调用很多异步方法,并且等待 所有方法完成后再继续执行,通过使用 Future.wait() 进行管理

    Future deleteDone = deleteLotsOfFiles();
    Future copyDone = copyLotsOfFiles();
    Future checksumDone = checksumLotsOfOtherFiles();
    
    Future.wait([deleteDone, copyDone, checksumDone])
        .then((List values) {
          print('Done with all the long steps');
        });
    
  2. Stream Dart|什么是 Stream

大概了解了 Dart 的语法,下节就开始写 Flutter 啦~,环境的安装具体查看官网,很详细 Flutter 环境安装 记得一定要配置镜像,配置镜像,配置镜像

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