Flutter 之 Dart语言基础详解 上篇

作者: 881ef7b85f62 | 来源:发表于2019-03-27 22:01 被阅读15次

经过了一个星期的React Native的学习和了解,感觉还是Flutter的优势会更高一些,而且从学习成本来说感觉做安卓的同学学习flutter会相对低一点,门槛会低很多。当然dart的基础笔者还是从其他朋友的资料总结而来,这里我尽可能的说的清楚一些!
文章纯干货!!!!!文末有福利!!!

首先是关键字(56个)

| 关键字 |
| abstract | do | import | super | as | dynamic | in | switch | assert | else | interface | sync* | enum | implements | is | this | async* | export | library | throw | await | external | mixin | true | break | extends | new | try | case | factory | null | typedef | catch | false | operator | var | class | final | part | void | const | finally rethrow | while | continue | for | return | with | covariant | get | set | yield* | default | if | static | deferred |

从上面的关键字里面可以看出和Java中的关键字还是有很多一样的,含义也是如此。

变量的声明

  1. var
  2. dynamic
  3. Objec

首先声明一个变量,变量的类型可以改变:

var name;
name = 'tom';
name = 123;

dynamic name;
name = 'tom';
name = 123;

Object name;
name = 'tom';
name = 123;

这里是不会报错的,说明变量的类型是可以改变的,并且都是可以print出来。

声明一个初始化的变量,变量类型不能再更改:

var name = 'tom';
name = 123;//这里是不对的,编译器会报错

这里声明一个name被发现时String类型的之后,就不能转变其他的类型了

但是:

dynamic 和 Object 声明的变量初始化后,变量的类型仍可改变:

dynamic name = 'tom';
name = 123;

Object name = 'tom';
name = 123;

这里dynamic和Object声明的类型是可以改变的。

使用确定类型显示声明变量,变量的类型不能再改变:

String name = 'tom';
name = 123;//这里已经定义name是Stiing类型的,就不能更改为int类型

默认值

看到这里我们想了解了,如果声明一个变量,没有初始值的时候他的默认值是什么呢?

dart里面的默认值都是null,一切皆对象,对象的默认值是null。

ar name;
assert(name == null);
print("assert pass");//可以正常打印

这里我们发现此处的断言是可以是真的,程序不会崩溃,说明默认值是null。

final 和 const

这两个关键字很重要
首先被这两个关键字修饰的变量,变量类型是可以省略的:

const age = 1;
final sex = '男';

被其修饰的变量无法更改其值,并且声明出来之后必须要进行初始化,相信学过Java的同学肯定对final这个关键字很熟悉了吧

var varList = const [1, 2, 3];
final finalList = const [1, 2, 3];
const constList = [1, 2, 3];
print([varList, finalList, constList]);
varList = [1];//这里允许更改
// constList = [1];//这里不允许更改
// finalList = [1];

可以更改非 final,非 const 变量的值,即使它曾经具有 const 值。

final List ls = [1, 2, 3];
ls[2] = 444;
print(ls);
const List cLs = [4, 5, 6];
cLs[1] = 4;
print("\n");
print(cLs);
这里同样是更改集合中某个元素的数值,final的是没有问题的,const的编译时没问题,但是运行起来会报错:

Unsupported operation: Cannot modify an unmodifiable list

不能更改一个不能修改的集合。

finalList1 = [1, 2, 3];
final finalList2 = [4, 5, 6];
print("\n");
print(identical(finalList1, finalList2)); //identical用于检查两个引用是否指向同一个对象
const constList1 = [1, 2];
const constList2 = [1, 2];
print("\n");
print(identical(constList1, constList2)); //identical用于检查两个引用是否指向同一个对象

这里相同的集合final声明的会在内存中重复创建,const声明的就不会重复创建,上面打印:

external bool indentical(Object a, Object b);这个方法传入两个引用来检测是否指向同一个对象,返回bool类型。

常量如果是类级别的,必须要使用 static const来修饰:

class C{
static const String a = 'hehe';
//这里只有类级别的常量的时候我们请使用static const来修饰,并且初始化
}
如果去掉static编译就会报错:Only static fields can be declared as const,只有静态字段可以声明为const。

内置类型

Number数值(num,int,double)

首先int和double都是num的子类,用法跟int和double一样,都是可以直接进行运算:

num n1 = 1;
num n2 = 1.0;
print('n1 + n2 = ${n1+n2}');

输出:
n1 + n2 = 2.0
自动识别double类型输出2.0不会丢失精度。

转换

转换这个环节是必不可少的,在Java中我们只int和double、float都是可以进行和String互相转换的,dart中也是可以的:

int i2 = int.parse('1');
print('i2---->{i2}'); double d2 = 1;//当 double 的值为 int 值时,int 自动转为 double print('d2:{d2}');
int i3 = int.tryParse('1.0');//返回 null
print('i3:${i3}');
输出如下:

这里细心地同学看到i3为什么输出是null,而不是1或者1.0呢,我们为什么调用tryParse而不用parse呢,试着去解析,如果有问题不会崩溃,个人理解这就是这个方法的真正的目的所在,1.0被识别出是double类型,我们用int去解析并且接受就会导致丢失精度的问题所以不予通过,方法会返回null,但是我们用parse来看看就发现程序崩溃了:

所以也就很容易理解了。

String 字符串

说道String,Java的同学肯定很熟悉啦,不过dart里面的String是UTF-16编码的,所以我们可以用单引号''或者双引号“”来声明字符串。

String string = 'haha';
String string1 = "hahaha";

都是ok的!

var name = 'HelloWorld';
//可以在字符串中使用表达式: {expression},如果表达式是一个标识符,可以省略 {}。 //如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串 var names = 'HelloWorld{name}';
//r 前缀可以创建一个 “原始 raw” 字符串
//加了r,转义符号 \n 换行 \t (按一次tab键的水平制表符)不起作用了
var rawNames = r"HelloWorld {name}"; print('name:{names}');
print('rawNames :${rawNames}');

这里我们发现${}表达式可以直接拿去变量值来进行输出,并且在字符串前面加上r只有会发现这个表达式效果失效了,那这也是dart的一个规则吧,可以试一下字符串里面加上 \n、\t等转义字符,会发现这些也都失效了,都被打印了出来!

看看下面代码:

//可以使用三个单引号或者双引号也可以 创建多行字符串对象
var multiLinesString = '''
Java
Android
Flutter''';
print('mutiLinesString:${multiLinesString}');
这里我们发现用了三个‘来声明一个字符串,这样得声明有何意义呢?看一下效果:

你们会发现竟然跟我们摆放的字符串格式一样,对的,他的含义就是这样!

接下来看一下StringBuffer的使用:

/// StringBuffer
var sb = StringBuffer(); //dart 2 可以省略 new
sb..write('aaa')..write('bbb')..write('ccc');//..级联符实现链式调用
sb.writeAll(['aaa','bbb','ccc'],',');//第二个参数表示分隔符,将第一个参数列表里的数据用这个分隔符拼接起来
print('sb:${sb}');
..的作用就是可以实现链式调用,writeAll方法:

external void writeAll(Iterable objects, [String separator = ""]);

方法点进去可以看到声明的时候我们需要传两个参数,集合、切割符号,这正如输出的结果我们看到确实如此!

Booleans 布尔值 (bool)

bool的运用很简单,跟Java是一样的:

bool isNull;
print('isNull:${isNull}');

运行结果:
大家肯定知道了,因为isNull没有初始化所以默认值肯定是null,那如果我们初始化之后输出就会如下:
isNull:false or isNull:true

List 列表(数组 List)

//声明一个自动长度的数组
List growableList = new List();
growableList..add(1)..add(2)..add('HelloWorld');
print('growbleList: ${growableList}');

这里我们用到了new这个关键字进行List实例的创建,通过..符号进行链式操作添加集合数据,打印如下:
growbleList: [1, 2, HelloWorld]
也可以换一种声明方式:

var list = List(6);
list[0] = "a";
list[1] = "b";
list[2] = "c";
list[3] = "d";
list[4] = "e";
list[5] = "f";
print('list:${list}');
这里我们声明了一个固定长度的集合并且挨个添加数据,打印如下:

list:[a, b, c, d, e, f]

我们还可以固定元素:

var typeList = List<String>();
typeList..add("1")..add("2")..add("3");
print('typeList:${typeList}');
如果放入其他的类型编译器就会报错。

还可以这样声明:

var varList = [1, 2, 3];

List ls = [1, 2, 3];
都是可以的。

还有List的一些常用方法,比如获取第一个元素、最后一个元素等,还可以直接增删、添加集合addAll等方法跟Java很类似,方法名都是顾名思义,很容易理解,这里就不一一列举了!

Maps 键值对集合 (Map)

Map的声明有两种方式:

1、直接声明,用{}表示,里面写key和value,每组键值对中间用逗号隔开。

Map companys = {'Alibaba': '阿里巴巴', 'Tencent': '腾讯', 'baidu': '百度'};
// 输出:{Alibaba: 阿里巴巴, Tencent: 腾讯, baidu: 百度}
print(companys);

2、先声明,再赋值

Map schoolsMap = new Map();//这里用var声明也是可以的
schoolsMap['first'] = '清华';
schoolsMap['second'] = '北大';
schoolsMap['third'] = '复旦';
// 打印结果 {first: 清华, second: 北大, third: 复旦}
print(schoolsMap);
看起来是不是也是很容易呢!

接下来看一下它的Api:
Map中的赋值可以这样做:

// Map的赋值,中括号中是Key,这里可不是数组
aMap[1] = '小米';

相同的Key可以覆盖value数值,key是唯一的,value可以时null也可以是空‘’。

// 检索Map是否含有某Key
assert(aMap.containsKey(1));

//删除某个键值对
aMap.remove(1);

可以看出它的api也是很容易,相比Java有些地方我觉得方便不少呢!

注意事项:

// 注意事项
// 1.map的key类型不一致也不会报错。
// 2.添加元素的时候,会按照你添加元素的顺序逐个加入到map里面,哪怕你的key,
// 比如分别是 1,2,4,看起来有间隔,事实上添加到map的时候是{1:value,2:value,4:value} 这种形式。
// 3.map里面的key不能相同。但是value可以相同,value可以为空字符串或者为null
Set 集合 (Set)

Set 集合 (Set)

set是无重复列表

看下面:

var dynamicSet = Set();
dynamicSet.add('a');
dynamicSet.add('b');
dynamicSet.add('c');
dynamicSet.add('1');
dynamicSet.add('1');
print('dynamicSet :${dynamicSet}');

这里会输出:
dynamicSet :{a, b, c, 1}
看到重复的不存在了!
set里面有一个方法difference(),用来返回两个set之间交集,比如,a.difference(b),则返回a有但是b没有的,反之则反。
intersection这个方法是返回两个集合的交集共有的;
union这个方法返回两个集合的并集。

Runes 符号字符

//Runes用于在字符串中表示Unicode字符 //https://copychar.cc/emoji/
String runesStr = '👄';
print(runesStr);
print(runesStr.length); //表示占 2 个 16 位字符
print(runesStr.runes.length); //表示占 1 个 32 位字符
Runes runes = new Runes('\u{1f605} \u6211');
var str1 = String.fromCharCodes(runes); //使用String.fromCharCodes显示字符图形
print(str1);
String str2 = '\u{1f605} \u6211'; //如果非4个数值,需要把编码值放到大括号中
print(str2);

上篇就到这里,下篇待续……
如果你从事Android开发,具备1年以上工作经验,希望深入浅出了解Android flutter、UI等技术要点,渴望实现技术和职业成长上的双重突破,那么以下福利就很适合你:

福利1 免费直播课程

《腾讯课堂Android高级开发工程师系列直播》

适听人群:Android中、高级开发工程师

3.20-3.23 连续7天每晚8点准时直播,持续进行

3月26日:还不会玩JVM就OUT了,一节课用实战告诉你正在直播

3月27日:架构师or码农—架构师必备Android AOP编程

3月28日:实现安全可靠的Android网络连接

3月29日:Handler源码分析与手写handler通信技术框架

3月30日:Android高级必备秘密武器-Navigation

3月31日:Android进阶必学-手写butterknife框架

4月1日:组件化架构演进之路-路由框架原理与实现

福利2 Android开发资料包

该资料包中主要包括「Java语言进阶与Android相关技术核」、「2)App开发框架知识体系(app亦对象)」、「360° Android app全方位性能调优」、「Android前沿技术」、「NDK 模块开发」等内容,全方位扩充你的知识体系。

想要参与Android进阶免费系列直播课

以及获取Android开发工程师资料包的同学,

点击加入:加入

免费课程,名额有限,先到先得~~

相关文章

网友评论

    本文标题:Flutter 之 Dart语言基础详解 上篇

    本文链接:https://www.haomeiwen.com/subject/efcxbqtx.html