【Flutter 极速指南】Dart 语言篇

这篇文章你能学习到:

  • 安装
  • Hello world
  • 基础语法
    • 基本规则
    • 关键词
    • 变量
    • 数据类型
  • 函数
  • 运算
  • 流程控制
  • 类&对象

安装

  • 安装
    • install homebrew
    • xcode-select --install
    • brew tap dart-lang/dart
    • brew install dart
  • 更新
    • brew update
    • brew upgrade dart
    • brew cleanup dart
  • dart --version

Hello world

class Hello {
  say() {
    print('Hello World');
  }
}

main() {
  new Hello().say();
}

运行:dart hello.dart

基础语法

基本规则

// Define a function.
printInteger(int aNumber) {
  print('The number is $aNumber.'); // Print to console.
}

// This is where the app starts executing.
main() {
  var number = 42; // Declare and initialize a variable.
  printInteger(number); // Call a function.
}

上面这段程序,几乎使用了 Dart 所有的语法:

// or /**/

注释,// 为单行注释,/**/ 为多行注释。

int

类型,Dart 还有例如 string、list、boolean 等内置类型。

42

数字类型字面量。

print()

显示输出方法。

'...' or "..."

字符串。

$variableName or ${expression}

字符串插值。

main()

主函数,程序的入口。

var

不指定类型的声明变量。

重要概念

  • 所有的变量都是 对象,每个对象都是通过一个 实例化的。数字、函数类型甚至是 null 都是对象。所有的对象都继承于 Object 类。
  • 尽管 Dart 是强类型语言,由于 Dart 可以自行推断类型,所以你可以不用声明类型。在上面的代码中,42 数字被推断为 int 类型,如果要明确说明不需要类型,请用特殊的类型 dynamic
  • Dart 支持泛型类型,例如 List<int>(整数列表)或 List<dynamic>(任何类型的对象列表)。
  • Dart 支持顶级函数(例如 main()),以及绑定到类或者对象的函数(静态或实例的方法),甚至可以在函数内创建函数。
  • 同样,Dart 支持顶级变量,以及绑定到类或者对象的变量(静态或实例的变量)。
  • 与 Java 不同,Dart 没有 publicprotectedprivate 关键词。如果标识符以下划线(_)开头,它就是私有的。
  • 标识符可以以字母或下划线(_)开头,后跟这些字符加数字的任意组合。
  • Dart 既有表达式(存在运行时值)也有语句(没有运行时值)。例如,条件表达式 condition ? expr1 : expr2,它的值是 expr1expr2。而 if-else 语句没有任何值。语句包含一个或多个表达式,但表达式不能直接包含语句。
  • Dart 会有两种类型的报错:警告和错误。警告:只会提示你的代码可能无法工作,但不会阻止代码执行。错误会发生在编译时或者运行时,编译时错误会阻止代码执行,运行时错误导致代码执行时发生异常。

关键词

参考:https://www.dartlang.org/guides/language/language-tour#keywords

变量

下面是一个创建变量和初始化变量的例子:

var name = 'Jay';

变量存储引用。变量名为 name 包含对 String 对象的引用,它的值为 “Jay”。

name 变量会自动推断为 String 类型,你也可以指定类型。如果对象不限于单个类型,可以通过指定 Object 或者 dynamic 类型来定义一个不限制类型的对象。

dynamic name = 'Jay';

变量的默认值

未初始化的变量的初始值为 null。即使是具有 number 类型的变量最初也是 null,因为 number 类型就像 Dart 其它类型一样都是对象。

int lineCount;
assert(lineCount == null);

Final 和 const

如果你不打算更改变量,可以使用 final 或者 const 来定义变量。这样变量只能设置一次值,const 变量是编译时常量。下面是创建和初始化一个常量:

final name = 'Jay';
final String nikname = 'Lily';

我们不能够改变一个常量:

name = 'Lee'; // Error: a final variable can only be set once.

如果你希望编译时定义常量,请使用 const 来定义变量。如果常量是类级别,请使用 static const。当你要设置一个编译时常量,你可以设置一个数字或者字符串、一个常量、甚至是对常量进行运算的结果:

const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

更多内容:https://www.dartlang.org/guides/language/language-tour#final-and-const

数据类型

Dart 中所有的数据都是对象,包括数字、函数等,它们都继承于 Object,并且默认值都是 null(包括数字)。以下是 Dart 内置数据类型:

  • number
    • int
    • double
  • string
  • boolean
  • list (array)
  • map
  • run
  • symbol

函数

Dart 是面向对象语言,甚至是函数也是一个对象,它的类型是 Function。这意味着函数可以作为一个参数传递给其它函数。你也可以通过 Dart 类型来实例化一个函数。

下面是创建函数的例子:

bool isNoble(int atomicNumber) {
    return _nobleGases[atomicNumber] != null;
}

Dart 推荐为公共接口提供类型,但是如果省略类型仍然有效:

isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

如果函数只有一个表达式,我们可以这样简写:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

=> expr 符号是 { return expr; } 简写。

可选参数

可选的命名参数

当调用函数是,我们可以通过 paramName: value 来指定参数名称,例如:

enableFlags(bold: true, hidden: false);

定义函数是,也可以用 {param1, param2, …} 来指定参数名称:

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold, bool hidden}) {...}

可选位置参数

参数默认值

main() 函数

每一个引用必须有一个顶级 main() 函数,作为程序的入口。

匿名函数

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

语法作用域

bool topLevel = true;

void main() {
    var insideMain = true;

    void myFunction() {
        var insideFunction = true;

        void nestedFunction() {
            var insideNestedFunction = true;

            assert(topLevel);
            assert(insideMain);
            assert(insideFunction);
            assert(insideNestedFunction);
        }
    }
}

闭包

/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
    return (num i) => addBy + i;
}

void main() {
    // Create a function that adds 2.
    var add2 = makeAdder(2);

    // Create a function that adds 4.
    var add4 = makeAdder(4);

    assert(add2(3) == 5);
    assert(add4(3) == 7);
}

返回值

运算

参考:https://www.dartlang.org/guides/language/language-tour#operators

流程控制

  • if and else
  • for loops
  • while and do-while loops
  • break and continue
  • switch and case
  • assert

以上条件语句基本上很多语言都有了,就不用一一举例了。但是要介绍一下 assert,它就像我们单元测试的断言一样,通过它可以判断传入的条件语句的真与假:

// Make sure the variable has a non-null value.
assert(text != null);

// Make sure the value is less than 100.
assert(number < 100);

// Make sure this is an https URL.
assert(urlString.startsWith('https'));

类&对象

Dart 是面向对象的语言,具有类和 mixin-based 的继承。每个对象都是一个类的实例,所有的类都继承于 Object。基于 mixin-based 的继承意味着,每个类只会有一个超类,但是类可以可以在多个类层次结构中重用。

类的成员

对象中类的成员包括函数和数据。当你调用一个函数时时,可以通过一个对象来调用,这种方式可以访问对象的函数和数据。

使用 . 来访问对象实例的数据和函数:

var p = Point(2, 2);

// Set the value of the instance variable y.
p.y = 3;

// Get the value of y.
assert(p.y == 3);

// Invoke distanceTo() on p.
num distance = p.distanceTo(Point(4, 4));

使用 ?. 代替 . 可以防止运算结果为 null 的异常。

// If p is non-null, set its y value to 4.
p?.y = 4;

构造函数

你可以通过构造函数来创建一个对象。构造函数可以通过 ClassName 或者 ClassName.identifier 来命名。例如:

var p1 = Point(2, 2);
var p2 = Point.fromJson({x: 1, y: 2});

通过 new 关键词也可以来创建一个对象:

var p1 = new Point(2, 2);
var p2 = new Point.fromJson({'x': 1, 'y': 2});

获取对象的类型

在运行时可以通过 Object 的 runtimeType 属性来获取对象的类型:

print('The type of a is ${a.runtimeType}');

到此为止,你已经知道如何使用类。接下来的部分讲告诉你如何实现类。

实例变量

下面是如何定义实例的变量:

class Point {
  num x; // Declare instance variable x, initially null.
  num y; // Declare y, initially null.
  num z = 0; // Declare z, initially 0.
}

所有的未初始化的实例的变量为 null

所有实例变量都会隐式生成 gettersetter 函数:

class Point {
    num x;
    num y;
}

void main() {
    var point = Point();
    point.x = 4; // Use the setter method for x.
    assert(point.x == 4); // Use the getter method for x.
    assert(point.y == null); // Values default to null.
}

构造函数

我们可以通过创建一个与类名相同的函数来定义一个构造函数。

class Point {
    num x, y;

    Point(num x, num y) {
        // There's a better way to do this, stay tuned.
        this.x = x;
        this.y = y;
    }
}

this 关键词是当前实例的引用。

将构造函数的参数赋值给实例是一个常见的操作,Dart 可以简单的操作:

class Point {
    num x, y;

    Point(this.x, this.y);
}

如果你没有定义构造函数,会有默认一个私有的构造函数。默认构造函数没有参数,并且在超类中调用无参数构造函数。

TODO

〖坚持的一俢〗

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

推荐阅读更多精彩内容