为什么80%的码农都做不了架构师?>>>
经过了一个星期的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中的关键字还是有很多一样的,含义也是如此。
变量的声明
- var
- dynamic
- 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。
var name; assert(name == null); print("assert pass");//可以正常打印
这里我们发现此处的断言是可以是真的,程序不会崩溃,说明默认值是null。
final 和 const
这两个关键字很重要
首先被这两个关键字修饰的变量,变量类型是可以省略的:
const age = 1; final sex = '男';
被其修饰的变量无法更改其值,并且声明出来之后必须要进行初始化,相信学过Java的同学肯定对final这个关键字很熟悉了吧D)
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
不能更改一个不能修改的集合。
final 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(); 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是无重复列表
看下面:
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);
上篇就到这里,下篇待续……