因为Flutter是以Dart语言为基础的,所以为了更好的理解Flutter,先学一下Dart。这个文章主要就是作为笔记的,记录的内容也比较简单,只记录了和java有差异的地方。
一、dart基础 语法学习
1.变量
dart 是一种强大的脚本语言,可以不预先定义变量类型,自动会类型推断
dart 中定义变量可以通过关键字var 也可以通过类型来生命变量
例如:
var str = ‘this is var ’;
String s = 'hello word';
int num = 123;
同时,dart中有类型校验,例如
var str = '';
str = 123;
时就会报错,因为str 已经是string类型了,不同赋值一个int类的数值
变量名称要由字母、数字、下划线和美元符号组成,不能以数字开头
和Java基本一致
2.常量 final 和const
const 值不变,一开始就要赋值
final可以开始不赋值 只能赋一次值
区别:final 不仅有const 的编译时常量的特性,最重要的是它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化的
例如
final data = new DateTime.now();
可以将第一次运行时获得的当前时间作为一个final的常量,但是
const data = new DateTime.now();就会报错,因为const是编译时常量
使用final或const修饰时,不使用var或其他变量类型
3.数据类型
(1)字符串类型
String str = 'this is a str';
String str2 = "this is a str2";
String str3 = ' ' 'this is a str3' ' ';
String str4 = " " " this is a str4" " ";
这四种方式都是可以的
区别: 后两种方式可以定义多行字符串
String str5 = ' ' ' this is a str
this is a str1
this is a str2 ' ' ';
这种方式是正确的,如果用前两种方式这样写会报错
字符串的拼接
String str1 = "abc";
String str2 = "efg";
print("$str1------$str2");
或print(str1 + str2);这种和Java中是一样的
(2)数值类型
dart中的数值类型是int (整型)和double(浮点类型)两种,当然也可以将整型数字直接赋给浮点类型的变量,这样就直接将整型的数提升为浮点类型,这里这个和Java中是一样的。
(3)布尔类型
bool a = true;
(4)list 类型(数组/集合)
第一种定义的方式
var l1 = ["aaa","bbb","ccc"];
print(l1)
print(l1.length);
print(l1[1]);
第二种定义的方式
var l2 = new List();
l2.add("张三");
l2.add("李四");
l2.add("王五");
print(l2);
print(l2[1]);
也可以指定集合中的数据类型
var str3 = new List<String>();
(5)Map类型,这个更像是json对象
第一种定义方式
var person={
"name":"张三",
"age":20
}
这里要注意,key必须加引号
print(person);
print(person["name"]);
print(person["age"]);
第二种定义方式
var p = new Map();
p["name"] = "李四";
p["age"] = 24;
print(p);
(6)类型变量判断
通过is关键字来判断
var str = '123';
if(str is String){
print("String 类型")
}else{
print("其他类型")
}
(7)其他类型
Runes 和 Symbols
4.运算符
(1)算数运算符 ~/ 取整运算符
int a = 13;
int b = 5;
print(a~/b);
结果为2
(2)赋值运算符 ??=
int b = 10;
b??=23; //表示当b为空的话,将23赋值给b,否则b还是原来的值
pirnt(b); //所以这里依旧输出10
(3)条件运算符 ??
var a;
var b = a ?? 10; //表示如果a为空的话将10赋值给b,否则将a赋值给b
5.类型转换
(1)Number类型和String类型之间的转换
String转换为Number类型 int.parse() 或者 double.parse();
String str = "123";
var a = int.parse(str);
Number转换为String类型 toString();
var num = 124;
var str = num.toString();
(2)isEmpty可以用来直接判断字符串是否为空串
var str=' ';
print(str.isEmpty);//为true
(3)isNaN
var myNum = 0/0;
if(myNum.isNaN){
print(‘NAN’)
}
二、集合List Set Map
1.List中常用的属性和方法
属性:length 长度
reversed 翻转
isEmpty 是否为空
isNotEmpty 是否不为空
方法:
add(value) 增加
addAll(list) 增加数组
indexOf(index) 按索引查找
remove(item) 删除具体的值
remove(index) 按照索引删除某一项
fillRange(start,end,item) 按照给出的索引修改内容
insert(index,value) 在指定位置插入
insertAll(index,list) 在指定位置插入一个list
toList() 将其他类型转换成list类型
join() List转换成字符串
split() 将字符串分割成list
2.Set用于去重
3.Map是无序的键值对
常用属性和方法
属性:keys 获取所有的key值
values 获取所有的value值
isEmpty 是否为空
isNotEmpty 是否不为空
方法:
remove(key) 删除指定key的数据
addAll({....}) 合并map,给映射内增加属性
containsValue 查看映射内的值 返回true/false
4.遍历集合
(1)普通for循环
(2)for ...in...语句
List list = ["aaa","bbb","ccc"];
for(var item in list){
...
}
(3)forEach方法
List list = ["aaa","bbb","ccc"];
list.forEach((value){print{"$value"}}); //forEach方法里传的参数是一个方法,这里方法可以去掉名称,value是方法的参数
(4)map方法
List list = [1,2,3];
var newList = list.map((value{
return value*2
}));
print(newList.toList);
(5)where返回满足条件的集合
List list = [1,2,3,5,8,7,9];
var newList = list.where((value{
return value>5; //把值大于5的返回去
}));
print(newList.toList);
(6)any
List list = [1,2,3,5,8,7,9];
var f= list.any((value{
return value>5; //只要集合里有一个数大于5就返回true
}));
print(f); //这里返回true
(7)every
List list = [1,2,3,5,8,7,9];
var f= list.every((value{
return value>5; //只要集合里所有的元素都要满足要求,才返回true
}));
print(f); //这里返回false
(8)map的forEach循环
Map person = {
"name":"张三",
“age”:21
}
person.forEach((key,value){ //这里需要两个参数的方法
print("$key---$value");
});
三、Dart中的方法
1.方法的写法
//main()方法是入口方法,要执行的代码要写在main方法中
main(){
//方法中可以嵌套方法
void func1(){
//func3的作用域是func1方法体里,不能再其他地方使用
void func3(){
}
}
}
//func2方法的作用域是全局的,在任何地方都可以调用
void func2(){
}
2.可选参数
//可选参数,即可以传入,也可以不传入的参数。用[]括起来,可以有多个
String getUserInfo(String name,[int age]){
if(age != null){
print("姓名:$name -------年龄:$age");
}else{
print("姓名:$name -------年龄保密");
}
}
3.默认参数
//默认参数,即传入参数时,使用的是传入的数值,不传参数使用默认的值
String getUserInfo(String name,[String sex='男',int age]){
if(age != null){
print("姓名:$name -------性别:$sex------年龄:$age");
}else{
print("姓名:$name -----性别:$sex--------年龄保密");
}
}
4.命名参数
String getUserInfo(String name,{int age,String sex='男'}){
if(age != null){
print("姓名:$name -------性别:$sex------年龄:$age");
}else{
print("姓名:$name -----性别:$sex--------年龄保密");
}
}
注意:在调用的时候的写法
getUserInfo('张飒',age:20,sex:'未知');
5.把方法当做参数传给另一个方法
//方法1
func1(){
print('func1');
}
//方法2,其中fun是方法参数,在func2中调用fun方法
func2(fun){
fun();
}
//调用func2这个方法,把func1作为参数传进去
func2(func1);
6.箭头函数
当方法体中只有一行代码的时候,可以使用箭头函数
//在集合list = [1,3,4,5,6]中,如果元素值>2,则将该值乘以2,否则保持不变,返回新集合
用普通函数如下:
List list = [1,3,4,5,6];
var newList = list.map((value){
if(value > 2){
return value*2;
}
return value;
})
print(newList.toList);
这里也可以用箭头函数
List list = [1,3,4,5,6];
var newList = list.map((value)=>value>2?value*2:value);//注意,这里不需要写return语句
print(newList.toList);
7.匿名方法
//这种写法更像是将一个方法赋值给一个变量,然后用这个变量调用方法
var fun = (){
print('this is an innominate fun');
}
main(){
fun();
}
8.自执行方法
//自执行方法不需要主动去调用,运行就可以自动调用
((int n){
print('自执行方法结果$n');
})(12); //这里 12就是传入的参数
执行结果:自执行方法结果12
9.方法递归
求1~100 的和
//定义一个方法
int sum = 0;
fun(int n){
sum += n;
if(n == 0){
return;
}
fun(n-1);
}
//调用这个方法
fun(100);
10.闭包
(1)全局变量:全局变量常驻内存,全局变量污染全局
(2)局部变量:不会常驻内存,会被垃圾机制回收,不会污染全局
var a = 124; //全局变量
main(){
void fun1(){
var b = 12; //局部变量
b++;
print(b);
}
void fun2(){
a++;
print(a);
}
fun2();
fun2();
fun1();
fun1();
}
结果:
125
126
13
13
(3)闭包:函数嵌套函数,内部函数会调用外部函数的变量或参数,变量或参数不会被系统回收
写法:函数嵌套函数,并return里面的函数,这样就形成了闭包
fun(){
var a = 123;
return(){
a++;
print(a);
};
}
var b = fun();
b();
b();
b();
结果:
124
125
126
另外,在字符串中同时拼接有方法调用的结果或者某个属性值时,可以按如下写法
print("结果:${a.result()}");
print("属性:${a.property}");