前言
Flutter应用程序使用Dart语言开发,Dart是面向对象编程语言,由Google于2011年推出,目前最新版本是2.0,为了更好的使用Flutter进行应用开发,本文将详细介绍Dart语言的语法和特性。
在学习Dart之前,先要了解以下Dart相关概念:
任何语言都有关键字,关键字是在编程时不能使用作为标识符的单词。Dart的关键字如下:
编码时应避免使用以上单词作为标识符,如果有必要,可以使用带有上标的单词作为标识符:
var name = "hi"; //String类型var age = 18; //int类型var high = 1.70; //double类型
如上变量定义后其类型已经确定,不可再将其他类型的值赋给变量。
var name = "hi"; //String类型name = 3; //此处编译器会报错,name被定义赋值之后已经是一个String类型,不可再赋值int类型值
String name = "bruce"; //String类型int age = 18; //int类型
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 = 18value = brucevalue = 3.5val = 18val = bruceval = 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 = nullvalue2 = nullvalue3 = nullvalue4 = null
如果不打算更改变量,可以使用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"); //创建对象时设置一次nameprint("p.name = ${p.name}"); //可正常输出 p.name = Brucep.name = "haha"; //编译器报错
Dart语言支持以下类型
String str1 = "hello"; //可以使用单引号或双引号print("str1 = $str1");String str2 = """Hi,BruceThis is Xiaoming."""; //使用带有单引号或双引号的三重引号可以创建多行字符串print("str2 = $str2");
输出结果为
str1 = hellostr2 = Hi,Bruce This is Xiaoming.
List arr = ["Bruce", "Nick", "John"];print("arr = $arr");
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'] = Brucemap1 = {1: hi, 2: hello, 3: yep}map1[1] = hi
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 = Bruceage = 18
和其他编程语言一样,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中使用到的运算符如下表格
DescriptionOperator一元后缀expr++ expr-- () [] . ?.一元前缀-expr !expr ~expr ++expr --expr乘除操作* / % ~/加减操作+ -移位<< >>按位与&按位异或^按位或|比较关系和类型判断>= > <= < as is is!等判断== !=逻辑与&&逻辑或||是否null??条件语句操作expr1 ? expr2 : expr3级联操作..分配赋值操作= *= /= ~/= %= += -= <<= >>= &=^= |= ??=
下面就对一些对于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
// 类定义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 = 20Uncaught exception:CastError: Instance of 'Banana': type 'Banana' is not a subtype of type 'Apple'
// 函数和类代码定义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的值,否则值为Nickprint("nickName = $nickName"); name = "Bruce";nickName = name ?? "Nick"; //如果name不为null,则nickName值为name的值,否则值为Nickprint("nickName = $nickName"); // 输出结果nickName = NicknickName = 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 = 20color = yellow
Dart中的控制流语句和其他语言一样,包含以下方式
以上控制流语句和其他编程语言用法一样,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 seedthis 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 paramthis is Apple constructor with no paramthis is Fruit constructor with no paramsay hello in Apple
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 paramthis is Apple constructor with no paramthis 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 bananaan apple
本文主要针对Dart不同于其他编程语言的一些语法特性进行了分析和举例,相信读过文本之后大家会对Dart语法有个很系统的了解,后边我们就可以开启Flutter应用开发之旅了。
转自:
https://mp.weixin.qq.com/s/lEUdry-pl40GuHPSYtPYpg