Flutter 之 Dart语言基础详解 上篇

为什么80%的码农都做不了架构师?>>> hot3.png

        经过了一个星期的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。

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

输出如下:

Flutter 之 Dart语言基础详解 上篇_第1张图片

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

 

Flutter 之 Dart语言基础详解 上篇_第2张图片

所以也就很容易理解了。

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

你可能感兴趣的:(java,移动开发)