Flutter 之 Dart语言基础详解 上篇

        经过了一个星期的React Native的学习和了解,感觉还是Flutter的优势会更高一些,而且从学习成本来说感觉做安卓的同学学习flutter会相对低一点,门槛会低很多。

        当然dart的基础笔者还是从其他朋友的资料总结而来,这里我尽可能的说的清楚一些!

首先是关键字(56个)

 

关键字---
abstractdoimportsuper
asdynamicinswitch
assertelseinterfacesync*
enumimplementsisthis
async*exportlibrarythrow
awaitexternalmixintrue
breakextendsnewtry
casefactorynulltypedef
catchfalseoperatorvar
classfinalpartvoid
constfinallyrethrowwhile
continueforreturnwith
covariantgetsetyield*
defaultifstaticdeferred

 

从上面的关键字里面可以看出和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。

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声明的就不会重复创建,上面打印:

f460e800c8668c5d5a64c4ae56bd5b3f3e7.jpg

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}');

输出如下:

cb4acf9f38897f392da1bfc33f2be52c02e.jpg

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

 

47221fd7497ae3b40f43590dbc7d6c43a76.jpg

所以也就很容易理解了。

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}');

这里我们发现用了三个‘来声明一个字符串,这样得声明有何意义呢?看一下效果:

045a9090d1ad32658673b4768f9cbc1ba62.jpg

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

接下来看一下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是无重复列表

看下面:

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);

上篇就到这里,下篇待续……

 

 

 

转载于:https://my.oschina.net/u/3761034/blog/3026466

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值