Dart语言快速入门:基础语法、数据类型、函数…

2019-06-1513:40:04编程语言入门到精通Comments2,978 views字数 7168阅读模式

谷歌推出Flutter跨平台UI框架后,对移动端的开发又产生了新的影响,Flutter采用Dart语言开发,而Flutter为什么选择Dart语言作为唯一的开发语言呢?总的来说,其拥有如下优势文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

  • Dart可基于AOT(Ahead Of Time)编译,即编译成平台的本地代码,运行性能高。
  • Dart也可基于JIT(Just In Time)编译,编译快速,可热加载,使开发周期加倍提升(Flutter亚秒级有状态热重载)
  • Dart可以更轻松地创建以60fps运行的流畅动画和转场。Dart在没有锁的情况下进行对象分配和垃圾回收
  • Dart语法结合Java与JavaScript语法特点,几乎没有令人不适的怪异语法,使Java程序员倍感亲切,快速上手

通常来说一门语言要么使用AOT编译,编译慢,开发效率低,或者使用JIT编译,在运行时编译,虽然可以热重载,但是执行效率低,而Dart在这两种之间做出了完美平衡,当开发时使用JIT编译,调试快,所见即所得,开发效率高,当发布时,使用AOT编译,编译成目标平台的本地代码,执行效率高。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

环境准备

安装Dart SDK

官方下载地址 共有三种SDK版本选择文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

  • Flutter
  • Web
  • Server

本章仅作为Dart编程语法学习,这里建议安装Server版的SDK,然后选择Windows版本进行下载。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

配置环境变量

在Windows上,通过点击下一步即可安装,安装完成后,需将dart-sdk下的的bin目录添加到系统Path环境变量中。这一步骤是通常的命令配置步骤。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

配置 VSCode 编辑器

作为Dart语言的学习,不建议下载笨重的IDE,官方提供支持VSCode 编辑器插件,建议使用VSCode 学习。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

官网下载 VSCode编辑器,安装完成后,启动VSCode并在插件商店中搜索Dart进行插件安装。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

测试环境

在VSCode中新建一个test.dart文件,编写如下代码文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

void  main(){
    print("hello world!");
}
复制代码

运行后成功在控制台输出hello world!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

基础语法

代码注释

Dart中的代码注释基本与Java语言相同文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 单行注释

/*
 * 多行注释
 */

/**
 * 文档注释
 */

/// 使用三个斜杠开头
/// 这是Dart特有的文档注释
复制代码

内置数据类型

Dart语言快速入门:基础语法、数据类型、函数…

在Dart中,所有能够使用变量引用的都是对象,每个对象都是一个类的实例。数字、函数和 null 也都是对象。所有的对象都继承于Object类。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

要注意,没有初始化的变量默认值为 null。数值类型变量的默认值也是 null文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

数值类型num有两个具体子类,分别为intdouble,其中int为整数值,范围是-2^532^53之间;double则是64位的双精度浮点数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

变量与常量

定义变量

Dart中定义变量有两种方式,一种是静态类型语言常用的方式,显式指定变量类型,另一种则是动态语言的常用方式,不指定类型,由vm自动推断。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 1.通过显式指定类型来定义变量
String name = "张三";
num age = 18;

// 2.使用关键字var,不指定类型
var address = "深南大道";
var id = 100;

/* 使用var定义变量,即使未显式指定类型,一旦赋值后类型就被固定
 * 因此使用var定义的变量不能改变数据类型
 */
var number = 19;
// 以下代码错误,无法运行,number变量已确定为int类型
number = "2019";
复制代码

如想动态改变变量的数据类型,应当使用dynamicObject来定义变量。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// dynamic声明变量
dynamic var1 = "hello";
var1 = 19;
print(var1);    // 19

// Object声明变量
Object var2 = 20;
var2 = "Alice";
print(var2);    // Alice
复制代码

建议在编写代码时,尽可能显式指定变量类型,这样可以提升代码可读性与调试的便利性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

定义常量

Dart中定义常量也有两种方式,一种使用final关键字,同Java中的用法, 一个 final 变量只能赋值一次;另一种是Dart的方式,使用const关键字定义。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 1.使用final关键字定义常量
final height = 10;

// 2.使用const关键字定义常量
const pi = 3.14;
复制代码

需要注意,final定义的常量是运行时常量,而const常量则是编译时常量,也就是说final定义常量时,其值可以是一个变量,而const定义的常量,其值必须是一个字面常量值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

final time = new DateTime.now(); // 正确
const time = new DateTime.now(); // 错误


const list = const[1,2,3];       // 正确
const list = [1,2,3];            // 错误
复制代码

内置类型的常用操作

数值类型

// String 转 int
var one = int.parse('1');

// String 转 double
var onePointOne = double.parse('1.1');

// int 转 String
String oneAsStr = 1.toString();

// double 转 String
String piAsStr = 3.14159.toStringAsFixed(2); // 保留两位 '3.14'

// Dart也支持整数位操作,<<、 >>、&、|
print((3 << 1) == 6);  // 0011 << 1 == 0110
print((3 >> 1) == 1);  // 0011 >> 1 == 0001
print((3 | 4)  == 7);  // 0011 | 0100 == 0111
复制代码

字符串

值得一提的是,Dart中提供的字符串插值表达式使字符串格式化变得异常方便。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 1.Dart可以使用单引号或双引号来创建字符串
var s1 = "hello";
var s2 = 'world';

// 2.类似Python,Dart可以使用三引号来创建包含多行的字符串
var multiLine1 = """你可以像这样,创建一个
包含了多行的字符串内容
""";

var multiLine2 = '''你也可以使用三个单引号,创建一个
包含了多行的字符串内容
''';

// 3.类似Python,还可以在字符串字面值的前面加上`r`来创建原始字符串,则该字符串中特殊字符可以不用转义
var path = r'D:\workspace\code';

// 4.Dart支持使用"+"操作符拼接字符串
var greet = "hello" + " world";

// 5.Dart提供了插值表达式"${}",也可以用于拼接字符串
var name = "王五";
var aStr = "hello,${name}";
print(aStr);    // hello,王五

// 当仅取变量值时,可以省略花括号
var aStr2 = "hello,$name"; // hello,王五

// 当拼接的是一个表达式时,则不能省略花括号
var str1 = "link";
var str2 = "click ${str1.toUpperCase()}";
print(str2);   // click LINK

// 6. 与Java不同,Dart使用"=="来比较字符串的内容
print("hello" == "world");
复制代码

布尔类型

Dart中的布尔类型用法同Java,仅有falsetrue两个值,不能使用0、非0或者null、非null来表达falsetrue。与Java不同的是,布尔类型的默认值为null文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

bool flags;
print(flags);    // null
复制代码

列表

Dart中列表操作与JavaScript中的数组相似。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 创建列表
var list = [1, 2, 3];
// 下标从0开始。使用length可以访问list的长度
print(list[0]);
print(list.length);

// 可以使用add添加元素
list.add(5);

// 可在list字面量前添加const关键字,定义一个不可改变的 列表(编译时常量)
var constantList = const [1, 2, 3];
constantList[1] = 1;     // 报错
复制代码

映射

又称为关联数组,相当于Java中的HashMap文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 1.通过字面量创建Map
var gifts = {
  'first' : 'partridge',
  'second': 'turtledoves',
  'fifth' : 'golden rings'
};

// 2.使用Map类的构造函数创建对象
var pic = new Map();
// 往Map中添加键值对
pic['first'] = 'partridge';
pic['second'] = 'turtledoves';
pic['fifth'] = 'golden rings';

// 3.获取Map的长度
print(pic.length);

// 4.查找Map
pirnt(pic["first"]);
print(pic["four"]);    // 键不存在则返回 null
复制代码

函数

在Dart中,函数(或方法) 也是对象,它的类型是 Function。 这意味着,函数可以赋值给变量,也可以当做其他函数的参数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

定义函数

Dart中定义函数,基本上与Java类似文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

String greet(String name){
    return "hello,$name";
}
复制代码

在Dart中,类型是可选,可以省略显式的类型,但仍然建议显式指定类型。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

greet(name){
    return "hello,$name";
}
复制代码

要注意,函数也是对象,所有函数都有返回值。当没有指定返回值的时候,函数会返回null。当然,如果你强行使用void来修饰函数,则函数真的没有返回值,这种情况就另当别论了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

函数的参数

Dart中支持两种可选参数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

  • 命名可选参数
  • 位置可选参数

在Java中通常使用方法重载来实现同名方法的不同参数调用,Dart中则可以通过可选参数来实现相同效果。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

命名可选参数

先来看一下命名参数,它使用花括号来定义参数列表文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 定义一个函数,参数列表用花括号包裹
enableFlags({bool bold, bool hidden}) {
    // do something
}

// 调用方式,传参时使用"参数名:值"的形式
enableFlags(hidden:true,bold:false);
复制代码

如果在定义函数时,给参数列表中的参数设置默认值,则该参数就是可选的,函数调用时可以忽略该参数,使用默认的值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 定义add函数
add({int x, int y=1, int z=0}){
    print(x + y + z;
}

// 调用
add(x:18);              // 19
add(x:18, y:2, z:10);   // 30
复制代码

这里需要注意一下,SDK 1.21之前的版本中,命名参数不能使用=号来设置默认值,而SDK 1.21之后,只能使用=号来设置默认值。因此,请检查并升级SDK版本。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

位置可选参数

位置可选参数使用中括号来定义参数列表,中括号中的参数是可选的文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 定义add函数
add(int x, [int y, int z]){
    int result = x;
    if (y !=  null){
        result = result + y;
    }

    if (z !=  null){
        result = result + z;
    }
    print(result);
}

// 调用
add(18);           // 18
add(18,12);        // 30
add(18, 12, 15);   // 45
复制代码

位置可选参数设置默认值文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 定义add函数
add(int x, [int y=0, int z=0]){
    print(x +y+z);
}
复制代码

最后需要注意一下命名可选参数位置可选参数的区别,前者中的参数与顺序无关,无需按顺序传参,且传参数时需使用冒号;后者与顺序相关,传参必须依照顺序。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

匿名函数

大部分函数都有名字,但我们也可以创建没有名字的函数,称为匿名函数,也被称为lambda表达式或者闭包。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 定义匿名函数,并将其赋值给一个变量func,注意,函数体最后的花括号处必须有分号结束。
var func = (x,y){
    return x + y;
};

print(func(10,11));    // 21
复制代码

注意,匿名函数与普通函数基本相同,也有参数列表,函数体,只是省去了函数名而已。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

箭头函数

Dart中的箭头函数与JavaScript中的基本相同。当函数体中只包含一个语句时,我们就可以使用=>箭头语法进行缩写。注意,箭头函数仅仅只是一个简洁表达的语法糖。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

普通函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

add(num x, num y){
    return x + y;
}

print(add(18,12));    // 30
复制代码

箭头函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 与上面的普通函数完全等价
add(num x, num y) => x + y;

print(add(18,12));    // 30
复制代码

箭头函数省略了花括号的表达,箭头后面跟一个表达式,函数的返回值也就是这个表达式的值。另外,箭头函数也可以与匿名函数结合,形成匿名箭头函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

var func = (num x, num y) => x + y;
复制代码

运算符

Dart语言中的运算符与Java中的绝大多数相同。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

算术运算符

+-*/%同Java语言文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

Dart中又多出了一个整除运算符~/,与普通除号的区别是将相除后的结果取整返回。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

类型判定运算符

以下是Dart增加的类型相关的运算符。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

操作符解释
as用于类型转换
is如果对象是指定的类型就返回 True
is!如果对象不是指定的类型返回 True

obj 实现了 T 的接口时, obj is T 才是 true。类似于Java中的instanceof文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

Dart中使用 as 操作符把对象转换为特定的类型,如无法转换则会抛出异常,因此在转换前最好使用is运算符进行检测。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 将p转换为Person类型再操作
(p as Person).name = 'Bruce';
复制代码

条件表达式

Dart中也支持三目表达式 condition ? expr1 : expr2文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

除此外,Dart还增加了非空条件判断符?? expr1 ?? expr2 上述运算表示,如果expr1的值不等于null,则返回其值; 否则执行表达式expr2并返回其结果。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

var str1 =  "Hello";
var str2 =  "world";
var result = str1 ?? str2.toUpperCase();
复制代码

级联运算符

我们通常使用.操作符调用对象的方法,这在Dart中也是支持的,但是Dart另外增加了一种级联运算符..,用两个点表示。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

级联运算符可以在同一个对象上连续调用多个方法以及访问成员变量。 使用它可以避免创建临时变量, 写出更流畅的代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

假如类Person有三个方法,setNamesetAgesave,则可如下调用文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

new Person()..setName("Bob")..setAge(20)..save();
复制代码

使用级联运算符调用方法,无需该方法返回对象本身即可连续的流式的调用该对象的其他方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

条件成员访问符

在Java中很容易碰到恼人的空指针错误,因此在方法调用前需要进行对象的非空判断,这样的判断语句使代码变得冗长,可读性差,不整洁。Dart中则发明了一个新的运算符用于处理此类情况。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

条件成员访问符?.,它和.类似,但是运算符左边的对象不能为null,否则返回null,若对象不为null,则返回对象本身。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// list1默认值为null
List list1;
print(list1?.length);  // null

List list2 = [];
print(list2?.length);  // 0
复制代码

分支与循环

条件分支

Dart中的条件分支基本与Java相同文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

if条件分支文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

if(i < 0){
  print('i < 0');
}else if(i == 0){
  print('i = 0');
} else {
  print('i > 0');
}
复制代码

switch条件分支文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// 在switch的case中可以使用整数、字符串、枚举类型和编译时常量
String command = 'OPEN';
switch (command) {
  case 'CLOSED':
    break;
  case 'OPEN':
    break;
  default:
    print('Default');
}
复制代码

循环语句

基本循环

Dart中的基本循环语句与Java相同文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

// for循环
for(int i = 0; i < 9; i++) {
  print(i);
}

// while循环
while(true){
  //do something
}

// do-while循环
do{
  //do something
} while(true);
复制代码

特有循环

var myList = ['Java','JavaScript','Dart'];

// for...in...循环,类似Java中的增强for
for (var it in myList ){
    print(it);
}

// forEach循环。其参数为一个Function对象,这里传入一个匿名函数
myList.forEach((var it){
    print(it);
});

// 可以使用匿名箭头函数简写
myList.forEach((it) => print(it));
复制代码

使用循环遍历Map文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

var myMap = {
'zhangsan':'201901',
'lisi':'201902',
'wangwu':'201902'
};

// forEach遍历Map
myMap.forEach((k, v) =>  print("$k : $v"));

// 根据键获取值来遍历。通过keys返回Map中所有键的集合
for(var k in myMap.keys){
    print("$k : ${myMap[k]}");
}

作者:编程之路从0到1
链接:https://juejin.im/post/5cdbf02ce51d45475f4de2ef
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/13664.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/13664.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定