dart学习笔记

前言
Flutter应用程序使用Dart语言开发,Dart是面向对象编程语言,由Google于2011年推出,目前最新版本是2.0,为了更好的使用Flutter进行应用开发,本文将详细介绍Dart语言的语法和特性。

一、重要概念
在学习Dart之前,先要了解以下Dart相关概念:

能够放在变量中的所有内容都是对象,每个对象都是一个类的实例。甚至于数字、函数和null值都是对象,并且所有对象都继承自Object类。
Dart是强类型语言,但类型标识是可选的,因为Dart可以推断类型。如果要明确说明不需要任何类型,可以使用特殊类型dynamic标识。
Dart支持泛型,如List或List(任何类型的对象列表)。
Dart支持顶级函数(例如main函数),以及绑定到类或对象的函数(分别是静态方法和实例方法)。函数内部也可以创建函数(嵌套函数或本地函数)。
Dart支持顶级变量,以及绑定到类或对象的变量(分别是静态变量和实例变量)。
与Java不同,Dart没有关键字public、protected和private。如想设置私有变量或函数,则变量和函数名以下划线()开头。
标识符可以以字母或下划线(
)开头,后跟这些字符加数字的任意组合。
Dart有两个表达式(具有运行时值)和语句(不具有)。 例如,条件表达式条件? expr1:expr2的值为expr1或expr2。 将其与if-else语句进行比较,该语句没有任何值。 语句通常包含一个或多个表达式,但表达式不能直接包含语句。
Dart工具可以报告两种问题:警告和错误。警告只是表明您的代码可能无法正常工作,但它们不会阻止您的程序执行。 错误可以是编译时或运行时。 编译时错误会阻止代码执行; 运行时错误导致代码执行时引发异常。
二、关键字
任何语言都有关键字,关键字是在编程时不能使用作为标识符的单词。Dart的关键字如下:

编码时应避免使用以上单词作为标识符,如果有必要,可以使用带有上标的单词作为标识符:

带有上标1的单词是上下文关键字,仅在特定位置有含义,它们在任何地方都是有效的;
带有上标2的单词是内置标识符,它们在大多数地方是有效的,但不能用作为类和类型名称或作为一个导入前缀;
带有上标3的单词是与Dart1.0发布后添加的异步支持相关的有限的保留字符,不能在任何标记为async,async * 或sync * 的任何函数体中使用await和yield作为标识符。
三、变量
变量的定义
1.可以使用var来定义变量,变量的类型可以通过变量值推断出来

var name = "hi"; //String类型
var age = 18; //int类型
var high = 1.70; //double类型
如上变量定义后其类型已经确定,不可再将其他类型的值赋给变量。

var name = "hi"; //String类型
name = 3; //此处编译器会报错,name被定义赋值之后已经是一个String类型,不可再赋值int类型值
2.也可以使用特定类型来定义变量

String name = "bruce"; //String类型
int age = 18; //int类型
3.如果变量不限于单个类型,则可以使用dynamic或Object来定义变量

dynamic value = 18;
print("value = value"); value = "bruce"; print("value =value");
value = 3.5;
print("value = $value");

Object val = 18;
print("val = val"); val = "bruce"; print("val =val");
val = 3.5;
print("val = $val");
输出结果为

value = 18
value = bruce
value = 3.5
val = 18
val = bruce
val = 3.5
变量的默认值
由于前文关于Dart的一些概念中说到过,能够放在变量中的所有内容都是对象,所以如果一个变量没有初始化值,那它的默认值就为null。

int value1;
print("value1 = value1"); bool value2; print("value2 =value2");
var value3;
print("value3 = value3"); dynamic value4; print("value4 =value4");
输出结果为

value1 = null
value2 = null
value3 = null
value4 = null
final 和 const
如果不打算更改变量,可以使用final或者const。一个final变量只能被设置一次,而const变量是编译时常量,定义时必须赋值。

// Person类
class Person {
static const desc = "This is a Person class"; //必须定义时赋值,否则编译时报错
final name;
Person(this.name); //对象初始化时赋值一次
}

// 定义一个Person对象
Person p = Person("Bruce"); //创建对象时设置一次name
print("p.name = ${p.name}"); //可正常输出 p.name = Bruce
p.name = "haha"; //编译器报错
四、内置类型
Dart语言支持以下类型

numbers : 包含int和double两种类型,没有像Java中的float类型,int和double都是num的子类型。

strings : Dart的字符串是一系列UTF-16代码单元。创建方法如下:

String str1 = "hello"; //可以使用单引号或双引号
print("str1 = str1"); String str2 = """Hi,Bruce This is Xiaoming. """; //使用带有单引号或双引号的三重引号可以创建多行字符串 print("str2 =str2");
输出结果为

str1 = hello
str2 = Hi,Bruce
This is Xiaoming.
booleans : Dart有一个名为bool的类型,只有两个对象具有bool类型:true和false,他们都是编译时常量。

lists : 和其他编程语言常见的集合一样,Dart中使用的集合是数组或有序的对象组。Dart中数组是List对象。

List arr = ["Bruce", "Nick", "John"];
print("arr = $arr");
maps
Map map = {
"name": "Bruce",
"age": 18,
"high": 1.70
};

print("map = map"); print("map['name'] ={map['name']}");

var map1 = {
1: "hi",
2: "hello",
3: "yep"
};
print("map1 = map1"); print("map1[1] ={map1[1]}");
输出结果为

map = {name: Bruce, age: 18, high: 1.7}
map['name'] = Bruce
map1 = {1: hi, 2: hello, 3: yep}
map1[1] = hi
runes
符文是字符串的UTF-32代码点。在字符串中表示32位Unicode值需要特殊语法,常用方法是 \uXXXX,其中XXXX是4位十六进制值,比如小心心(♥)是\u2665。要指定多于或少于4个十六进制数字,请将值放在大括号中。 比如,微笑(😆)是\u{1f600}。
String smile = '\u{1f600}';
print("微笑:$smile");

Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(String.fromCharCodes(input));
输出结果为

微笑:😀
♥ 😅 😎 👻 🖖 👍
五、函数
Dart是一种真正的面向对象语言,因此即使是函数也是对象并且具有类型Function。这意味着函数可以分配给变量或作为参数传递给其他函数。

定义方法
和绝大多数编程语言一样,Dart函数通常的定义方式为

String getName() {
return "Bruce";
}
如果函数体中只包含一个表达式,则可以使用简写语法

String getName() => "Bruce";
可选参数
Dart函数可以设置可选参数,可以使用命名参数也可以使用位置参数。

命名参数,定义格式如 {param1, param2, …}

// 函数定义
void showDesc({var name, var age}) {
if(name != null) {
print("name = name"); } if(age != null) { print("age =age");
}
}

// 函数调用
showDesc(name: "Bruce");

// 输出结果
name = Bruce
位置参数,使用 [] 来标记可选参数。

// 函数定义
void showDesc(var name, [var age]) {
print("name = $name");

if(age != null) {
print("age = $age");
}
}

// 函数调用
showDesc("Bruce");

// 输出结果
name = Bruce
默认值
函数的可选参数也可以使用 = 设置默认值

// 函数定义
void showDesc(var name, [var age = 18]) {
print("name = $name");

if(age != null) {
print("age = $age");
}
}

// 函数调用
showDesc("Bruce");

// 输出结果
name = Bruce
age = 18
main函数
和其他编程语言一样,Dart中每个应用程序都必须有一个顶级main()函数,该函数作为应用程序的入口点。

函数作为参数
Dart中的函数可以作为另一个函数的参数。

// 函数定义
void println(String name) {
print("name = $name");
}

void showDesc(var name, Function log) {
log(name);
}

// 函数调用
showDesc("Bruce", println);

// 输出结果
name = Bruce
匿名函数
// 函数定义
void showDesc(var name, Function log) {
log(name);
}

// 函数调用,匿名函数作为参数
showDesc("Bruce", (name) {
print("name = $name");
});

// 输出结果
name = Bruce
嵌套函数
Dart支持嵌套函数,也就是函数中可以定义函数。

// 函数定义
void showDesc(var name) {
print("That is a nested function!");

//函数中定义函数
void println(var name) {
print("name = $name");
}

println(name);
}

// 函数调用
showDesc("Bruce");

// 输出结果
That is a nested function!
name = Bruce
六、运算符
Dart中使用到的运算符如下表格

Description Operator
一元后缀 expr++ expr-- () [] . ?.
一元前缀 -expr !expr ~expr ++expr --expr
乘除操作 * / % ~/
加减操作 + -
移位 << >>
按位与 &
按位异或 ^
按位或 I
比较关系和类型判断 >= > <= < as is is!
等判断 == !=
逻辑与 &&
逻辑或 II
是否null ??
条件语句操作 expr1 ? expr2 : expr3
级联操作 ..
分配赋值操作 = . *= . /= . ~/= . %= . += . -= . <<= . >>= . &= . ^= . I= . ??=
下面就对一些对于Java或Objective-C来说未使用过的运算符通过代码来做个介绍。

?.的使用

//定义类
class Person {
var name;
Person(this.name);
}

// 调用
Person p;
var name = p?.name; //先判断p是否为null,如果是,则name为null;如果否,则返回p.name值
print("name = $name");

// 输出结果
name = null
~/的使用

// 代码语句
var num = 10;
var result = num ~/ 3; //得出一个小于等于(num/3)的最大整数
print("result = $result");

// 输出结果
result = 3
as的使用,as用来做类型转化

// 类定义
class Banana {
var weight;
Banana(this.weight);
}

class Apple {
var weight;
Apple(this.weight);
}

// 调用
dynamic b = Banana(20);
(b as Banana).weight = 20; // 正常执行
print("b.weight = {(b as Banana).weight}"); (b as Apple).weight = 30; // 类型转换错误,运行报错 print("b.weight ={(b as Apple).weight}");

//输出结果
b.weight = 20
Uncaught exception:
CastError: Instance of 'Banana': type 'Banana' is not a subtype of type 'Apple'
is的使用

// 函数和类代码定义
getFruit() => Banana(20); // 获取一个水果对象

class Banana {
var weight;
Banana(this.weight);
}

class Apple {
var color;
Apple(this.color);
}

// 调用
var b = getFruit();
if(b is Apple) { //判断对象是否为Apple类
print("The fruit is an apple");
} else if(b is Banana) { //判断水果是否为Banana类
print("The fruit is a banana");
}

// 输出结果
The fruit is a banana
??的使用

// 操作代码块
String name;
String nickName = name ?? "Nick"; //如果name不为null,则nickName值为name的值,否则值为Nick
print("nickName = $nickName");

name = "Bruce";
nickName = name ?? "Nick"; //如果name不为null,则nickName值为name的值,否则值为Nick
print("nickName = $nickName");

// 输出结果
nickName = Nick
nickName = Bruce
..的使用,级联操作允许对同一个对象进行一系列操作。

// 类定义
class Banana {
var weight;
var color;
Banana(this.weight, this.color);

void showWeight() {
print("weight = $weight");
}

void showColor() {
print("color = $color");
}
}

// 调用
Banana(20, 'yellow')
..showWeight()
..showColor();

// 输出结果
weight = 20
color = yellow
七、控制流语句
Dart中的控制流语句和其他语言一样,包含以下方式

if and else
for循环
while和do-while循环
break和continue
switch-case语句
以上控制流语句和其他编程语言用法一样,switch-case有一个特殊的用法如下,可以使用continue语句和标签来执行指定case语句。

var fruit = 'apple';
switch (fruit) {
case 'banana':
print("this is a banana");
continue anotherFruit;

anotherFruit:
case 'apple':
print("this is an apple");
break;
}

// 输出结果
this is an apple
八、异常
Dart的异常捕获也是使用try-catch语法,不过与java等语言稍有不同

// 定义一个抛出异常的函数
void handleOperator() => throw Exception("this operator exception!");

// 函数调用
try {
handleOperator();
} on Exception catch(e) {
print(e);
} finally { // finally语句可选
print("finally");
}

// 输出结果
Exception: this operator exception!
finally
九、类
Dart是一种面向对象的语言,具有类和基于mixin的继承。同Java一样,Dart的所有类也都继承自Object。

构造函数
Dart的构造函数同普通函数一样,可以定义无参和有参,命名参数和位置参数,可选参数和给可选参数设置默认值等。Dart的构造函数有以下几个特点:

可以定义命名构造函数
可以在函数体运行之前初始化实例变量
子类不从父类继承构造函数,定义没有构造函数的子类只有无参无名称的构造函数
子类定义构造函数时默认继承父类无参构造函数,也可继承指定有参数的构造函数;
命名构造函数和函数体运行前初始化实例变量
// 类定义
class Tree {
var desc;

// 命名构造函数
Tree.init() {
desc = "this is a seed";
}

// 函数体运行之前初始化实例变量
Tree(var des) : desc = des;
}

// 构造函数调用
Tree t = Tree.init();
print("${t.desc}");

Tree t1 = Tree("this is a tree");
print("${t1.desc}");

// 输出结果
this is a seed
this is a tree
构造函数继承
// 类定义
class Fruit {
Fruit() {
print("this is Fruit constructor with no param");
}

Fruit.desc(var desc) {
print("$desc in Fruit");
}
}

class Apple extends Fruit {
Apple():super() {
print("this is Apple constructor with no param");
}

// 默认继承无参构造函数
Apple.desc(var desc) {
print('$desc in Apple');
}
}

// 构造函数调用
Apple();
Apple.desc("say hello");

// 输出结果
this is Fruit constructor with no param
this is Apple constructor with no param
this is Fruit constructor with no param
say hello in Apple
mixin继承
mixin是一种在多个类层次结构中重用类代码的方法。

// 类定义
class LogUtil {
void log() {
print("this is a log");
}
}

class Fruit {
Fruit() {
print("this is Fruit constructor with no param");
}
}

class Apple extends Fruit with LogUtil {
Apple():super() {
print("this is Apple constructor with no param");
}
}

// 调用
Apple a = Apple();
a.log(); //可执行从LogUtil继承过来的方法

// 输出结果
this is Fruit constructor with no param
this is Apple constructor with no param
this is a log
十、泛型
Dart同Java一样,也支持泛型。

// 类定义
class Apple {
var desc;
Apple(this.desc);

void log() {
print("${this.desc}");
}
}

class Banana {
var desc;
Banana(this.desc);

void log() {
print("${this.desc}");
}
}

class FruitFactory<T> {
T produceFruit(T t) {
return t;
}
}

// 调用
FruitFactory<Banana> f = FruitFactory<Banana>();
Banana b = f.produceFruit(Banana("a banana"));
b.log();

FruitFactory<Apple> f1 = FruitFactory<Apple>();
Apple a = f1.produceFruit(Apple("an apple"));
a.log();

// 输出结果
a banana
an apple
写在最后
本文主要针对Dart不同于其他编程语言的一些语法特性进行了分析和举例,相信读过文本之后大家会对Dart语法有个很系统的了解,后边我们就可以开启Flutter应用开发之旅了。

来源:https://blog.csdn.net/weixin_43499085/article/details/88816331

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

推荐阅读更多精彩内容