一、dart基本语法
Dart介绍:
Dart是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。
Dart诞生于2011年,号称要取代JavaScript。
官网:https://dart.dev/
Dart环境搭建:
1、本地开发Dart程序,首先需要安装Dart Sdk
官方文档:https://dart.dev/get-dart
windows(推荐):http://www.gekorm.com/dart-windows/
mac:如果mac电脑没有安装brew这个工具首先第一步需要安装它:https://brew.sh/
brew tap dart-lang/dart
brew install dart
Dart 开发工具:
Dart的开发工具有很多: IntelliJ IDEA 、 WebStorm、 Atom、Vscode等
以Vscode中配置Dart为例:
vscode插件安装 dart、 code runner、 Code Runner 可以运行我们的文件
1.入口方式两种定义方式
main(){
var name = '信息技术';
var price= 23.55;
print(name); //信息技术
print(price);//23.55
}
//第二种方式:没有返回值
void main(){
var name = '信息技术';
var price= 23.55;
print(name); //信息技术
print(price);//23.55
}
1.1变量声明
Dart 变量:var
dart是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推倒
dart中定义变量可以通过var关键字可以通过类型来申明变量
如:
main(){
var str='this is var';
String str='this is var'; //报错
int str=123; //报错
//注意: var 后就不要写类型 , 写了类型 不要var 两者都写 var a int = 5; 报错
var str1='this is a str';
str1='你好 str';
print(str1);
int myNum=1234;
myNum=4567;
print(myNum);
}
Dart 常量: final 和 const修饰符
const值不变 一开始就得赋值;final 可以开始不赋值 只能赋一次 ; 而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化永远不改量的量,请使用final或const修饰它,而不是使用var或其他变量类型。
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
void main(){
//const常量
// const PI=3.14159;
// PI=123.1243; //错误的写法 常量不可以修改
// print(PI);
// final 常量
// final PI=3.14159;
// PI=124214.214124; //错误写法
// print(PI);
final a=new DateTime.now();
print(a); //2019-05-10 15:59:02.966122
//const a=new DateTime.now(); //报错了
}
//区别:final 可以开始不赋值 只能赋一次 ; 而final不仅有const的编译时常量的特性,
//最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化
void main(){
//字符串
// String str='你好dart';
// print(str);
//数字类型
// int myNum=12354;
// print(myNum);
//dart里面有类型校验
// var str='';
// str=1234;
// print(str);
String str="2131242";
print(str);
int myNum=1243214;
print(myNum);
}
2、dart 基本数据类型
2.1 常用数据类型
Numbers(数值): int, double
Strings(字符串):String
Booleans(布尔):bool
List(数组): 在Dart中,数组是列表对象,所以大多数人只是称它们为列表
Maps(字典): 通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个 键 只出现一次, 而一个值则可以出现多次
2.2、项目中用不到的数据类型 (用不到
)
<kbd>Runes </kbd>
Rune是UTF-32编码的字符串。它可以通过文字转换成符号表情或者代表特定的文字。
main() {
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
}
Symbols
Symbol对象表示在Dart程序中声明的运算符或标识符。您可能永远不需要使用符号,但它们对于按名称引用标识符的API非常有用,因为缩小会更改标识符名称而不会更改标识符符号。要获取标识符的符号,请使用符号文字,它只是#后跟标识符:
在 Dart 中符号用 # 开头来表示,入门阶段不需要了解这东西,可能永远也用不上。 http://dart.goodev.org/guides/libraries/library-tour#dartmirrors—reflection
2.2、数据类型示例
/*
Dart数据类型:字符串类型
*/
void main(){
//1、字符串定义的几种方式
// var str1='this is str1';
// var str2="this is str2";
// print(str1);
// print(str2);
// String str1='this is str1';
// String str2="this is str2";
// print(str1);
// print(str2);
// String str1='''this is str1
// this is str1
// this is str1
// ''';
// print(str1);
// String str1="""
// this is str1
// this is str1
// this is str1
// """;
// print(str1);
//2、字符串的拼接
String str1='你好';
String str2='Dart';
// print("$str1 $str2");
print(str1 + str2);
print(str1 +" "+ str2);
}
/*
Dart数据类型:数值类型
int
double
*/
void main(){
//1、int 必须是整型
int a=123;
a=45;
print(a);
//2、double 既可以是整型 也可是浮点型
double b=23.5;
b=24;
print(b);
//3、运算符
// + - * / %
var c=a+b;
print(c);
}
/*
Dart数据类型:布尔类型
bool 值true/false
*/
void main(){
//1、bool
// bool flag1=true;
// print(flag1);
// bool flag2=false;
// print(flag2);
//2、条件判断语句
var flag=true;
if(flag){
print('真');
}else{
print('假');
}
var a=123;
var b='123';
if(a==b){
print('a=b');
}else{
print('a!=b');
}
}
/*
Dart数据类型: List(数组/集合)
*/
void main() {
//1、第一种定义List的方式
var list1 = ["codeSE", 100, 'A', true];
print(list1); //[codeSE, 100, A, true]
print(list1.length); //4
print(list1[0]); //codeSE
//2、第二种定义List的方式 指定类型
var list2 = <String>['codeSE', 'ank'];
var list3 = <int>[12, 34, 456, 9000];
//3、第三种定义List的方式 增加数据 ,通过[]创建的集合它的容量可以变化
var list4 = [];
print(list4.length);
list4.add("codeSE");
list4.add(123);
list4.add(false);
print(list4);
//4、第四种定义List的方式
// var list6=new List(); //在新版本的dart(已被弃用)
var list6 = List.filled(2, ""); //创建一个固定长度的集合
print(list6); //[,]
print(list6[0]); //
list6[0] = "codeSE"; //修改集合的内容
list6[1] = "李四";
print(list6); //[codeSE, 李四]
// list6.add("王五"); //错误写法 通过List.filled创建的集合长度是固定 没法增加数据
//通过List.filled创建的集合长度是固定
var list7 = List.filled(2, "");
print(list7.length); //2
// list7.length = 0; //修改集合的长度 报错
var list8 = <String>["codeSE", "李四"];
print(list8.length); //2
list8.length = 0; //可以改变的
print(list8); //[]
var list9 = List<String>.filled(2, "");
list9[0] = "string";
// list8[0]=222; //报错
print(list9); //[string, ]
}
}
/*
Dart数据类型: Maps(字典)
*/
/*
Dart数据类型: Maps(字典)
*/
void main() {
//第一种定义 Maps的方式
var person = {
"name": "codeSE",
"age": 20,
"work": ["程序员", "送外卖", "擦地板"]
};
print(person);
print(person["name"]);
print(person["age"]);
print(person["work"]);
//第二种定义 Maps的方式
var p = new Map();
p["name"] = "codeSE";
p["age"] = 22;
p["work"] = ["程序员", "送外卖", "擦地板"];
print(p);
print(p["age"]);
}
/*
Dart判断数据类型
is 关键词来判断类型
*/
void main() {
var str = '1234';
if (str is String) {
print('是string类型');
} else if (str is int) {
print('是int类型');
} else {
print('其他类型');
}
var num = 123;
if (num is String) {
print('是string类型');
} else if (num is int) {
print('是int类型');
} else {
print('其他类型');
}
}
3、运算符 条件判断 类型转换
运算名 | 操作符 |
---|---|
算术运算符 | + - * / ~/ (取整) %(取余) |
关系运算符 | == != > < >= <= |
逻辑运算符 | ! && |
赋值运算符 | = ??= += -= *= /= %= ~/= |
条件表达式 | if else switch case |
三目运算符 | ??运算符: |
备注:??=
如果前面的值为空则赋值给他 var str= "";str??=="codeSE";
void main(List<String> args) {
int b = 0;
b ??= 23;
print(b);
//2、条件运算符
var sex = "女1";
switch (sex) {
case "男":
print('性别是男');
break;
case "女":
print('性别是女');
break;
default:
print('传入参数错误');
break;
}
bool flag = false;
String i = flag ? '我是true' : '我是false';
print(i); //我是false
//3、 ??运算符
var a;
var b = a ?? 10;
print(b); //10
var c = 22;
var d = c ?? 10;
print(d); //22
void main() {
// 1、Number与String类型之间的转换
// Number类型转换成String类型 toString()
// String类型转成Number类型 int.parse()
String str1 = '123';
var myNum1 = int.parse(str1);
print(myNum1 is int); //true
String str2 = '123.1';
var myNum2 = double.parse(str2);
print(myNum2 is double); //true
print(myNum2); //123.1
String price1 = '12';
var myNum3 = double.parse(price1);
print(myNum3); //12.0
print(myNum3 is double); //true
// 报错
String price2 = '';
// var myNum4 = double.parse(price2);
// print(myNum4);
// print(myNum4 is double);
// try ... catch
String price3 = '';
try {
var myNum5 = double.parse(price3);
print(myNum5);
} catch (err) {
print(0); //0
}
var myNum6 = 12;
var str3 = myNum6.toString();
print(str3 is String); //true
// 2、其他类型转换成Booleans类型
// isEmpty:判断字符串是否为空
var str4 = '';
if (str4.isEmpty) {
print('str4空');
} else {
print('str4不为空');
}
var myNum7 = 123;
if (myNum7 == 0) {
print('0');
} else {
print('非0');
}
var myNum8;
if (myNum8 == 0) {
print('0');
} else {
print('非0');
}
var myNum9;
if (myNum9 == null) {
print('空');
} else {
print('非空');
}
var myNum10 = 0 / 0;
print(myNum10); //NaN
if (myNum10.isNaN) {
print('NaN');
}
}
4、循环语句
++ --表示自增 自减 1
在赋值运算里面 如果++ --写在前面 这时候先运算 再赋值,如果++ --写在后面 先赋值后运行运算
4.1 for循环
void main(List<String> args) {
/*
for (int i = 1; i<=100; i++) {
print(i);
}
//第一步,声明变量int i = 1;
//第二步,判断i <=100
//第三步,print(i);
//第四步,i++
//第五步 从第二步再来,直到判断为false
*/
var sum = 0, total = 1;
for (var i = 1; i <= 10; i++) {
sum += i;
total *= i;
}
print(sum);
print(total);
List list = [
{
"cate": '《阿里》',
"news": [
{"title": "支付宝"},
{"title": "淘宝"},
{"title": "蚂蚁森林"}
]
},
{
"cate": '《腾讯》',
"news": [
{"title": "微信"},
{"title": "QQ"},
{"title": "王者荣耀"}
]
}
];
for (var i = 0; i < list.length; i++) {
print(list[i]["cate"]);
print('-------------');
for (var j = 0; j < list[i]["news"].length; j++) {
print(list[i]["news"][j]["title"]);
}
}
}
4.2 do while ,break
语法格式:
while(表达式/循环条件){
}
do{
语句/循环体
}while(表达式/循环条件);
注意: 1、最后的分号不要忘记
2、循环条件中使用的变量需要经过初始化
3、循环体中,应有结束循环的条件,否则会造成死循环。
void main(List<String> args) {
//求1+2+3+4 ...+100的和
int i = 1;
var sum = 0;
while (i <= 100) {
sum += i;
i++;
}
print(sum); //5050
int j = 1;
var total = 0;
do {
total += j;
j++;
} while (j <= 100);
print(total); //5050
//while 和 do while的区别 第一次循环条件不成立的情况下
int k = 10;
while (k < 2) {
print('执行代码');
}
var m = 10;
do {
print('执行代码');
} while (m < 2);
}
break语句功能:
1、在switch语句中使流程跳出switch结构。
2、在循环语句中使流程跳出当前循环,遇到break 循环终止,后面代码也不会执行
强调:
1、如果在循环中已经执行了break语句,就不会执行循环体中位于break后的语句。
2、在多层循环中,一个break语句只能向外跳出一层
break可以用在switch case中 也可以用在 for 循环和 while循环中
continue语句的功能:
【注】只能在循环语句中使用,使本次循环结束,即跳过循环体重下面尚未执行的语句,接着进行下次的是否执行循环的判断。
continue可以用在for循环以及 while循环中,但是不建议用在while循环中,不小心容易死循环
main() {
//1、如果i等于4的话跳过
for (var i = 1; i <= 10; i++) {
if (i == 4) {
continue; /*跳过当前循环体 然后循环还会继续执行*/
}
print(i); // 1 2 3 5 6 7 8 9 10
}
//2、如果 i等于4的话跳出循环
for (var i = 1; i <= 10; i++) {
if (i == 4) {
break; /*跳出循环体*/
}
print(i); // 1 2 3
}
//3、break语句只能向外跳出一层
for (var i = 0; i < 5; i++) {
print('外层---$i');
for (var j = 0; j < 3; j++) {
if (j == 1) {
break;
}
print('里层$j');
}
}
//4、while循环 break跳出循环
var i = 1;
while (i <= 10) {
if (i == 4) {
break;
}
print(i);
i++;
} // 1 2 3
var sex = "男";
switch (sex) {
case "男":
print('男');
break;
case "女":
print('女');
break;
default:
print('默认');
} // 男
}
5、数组常用属性及方法
常用属性:
属性 | 描述 |
---|---|
length | 长度 |
reversed | 翻转 |
isEmpty | 是否为空 |
isNotEmpty | 是否不为空 |
void main(List<String> args) {
/*
*常用属性:
length 长度
reversed 翻转
isEmpty 是否为空
isNotEmpty 是否不为空
*/
// var list1 = ['CodeSE', 100, '45', true];
List list1 = ['CodeSE', 100, '45', true];
print(list1.length); //4
print(list1.reversed); //(true, 45, 100, CodeSE)
print(list1.isEmpty); //false
print(list1.isNotEmpty); //true
常用方法:
方法 | 描述 |
---|---|
add | 增加 |
addAll | 拼接数组 |
indexOf | 查找 传入具体值 |
remove | 删除 传入具体值 |
removeAt | 删除 传入索引值 |
fillRange | 修改 |
insert(index,value); | 指定位置插入 |
insertAll(index,list) | 指定位置插入List |
toList() | 其他类型转换成List |
join() | List转换成字符串 |
split() | 字符串转化成List |
forEach | |
map | |
where | |
any | |
every |
/*
*常用方法:
add 增加
addAll 拼接数组
indexOf 查找 传入具体值
remove 删除 传入具体值
removeAt 删除 传入索引值
fillRange 修改
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
toList() 其他类型转换成List
join() List转换成字符串
split() 字符串转化成List
forEach
map
where
any
every
*/
var list2 = ['Java', 'JavaScript', "Python", "中国", '数据', '应用'];
list2.add('CodeSE');
list2.addAll(['100', 'Blue']);
print(list2);
var newList2 = list2.reversed.toList(); //toList(),转化为数组
print(newList2); //[Blue, 100, CodeSE, 应用, 数据, 中国, Python, JavaScript, Java]
print(list2.indexOf('Python')); //2
list2.remove('Java'); //按元素名称移除元素
list2.removeAt(2); //按元素所在的位置移除
print(list2); //[JavaScript, Python, 数据, 应用, CodeSE, 100, Blue]
print(
'=================================================================================');
var list3 = ['香蕉', '苹果', '西瓜', '菠萝', '哈密瓜', '柚子'];
list3.fillRange(1, 3, '葡萄'); //修改替换操作:start end 值
print(list3); //[香蕉, 葡萄, 葡萄, 菠萝, 哈密瓜, 柚子]
list3.insert(3, '白菜'); //插入 一个
print(list3); //[香蕉, 葡萄, 葡萄, 白菜, 菠萝, 哈密瓜, 柚子]
list3.insertAll(4, ['AA', 'MM']); //插入多个
print(list3); //[香蕉, 葡萄, 葡萄, 白菜, AA, MM, 菠萝, 哈密瓜, 柚子]
print(
'=================================================================================');
var list4 = ['菠萝', '哈密瓜', '柚子'];
var str = list4.join('--');
print(str); //菠萝--哈密瓜--柚子
print(str is String); //true
var text = '菠萝--哈密瓜--柚子';
var arr = text.split('--');
print(arr); //[菠萝, 哈密瓜, 柚子]
}
6、Set集合
set是无序的不可重复的集合,不能通过索引获取。一般功能是:数组去重
。
void main(List<String> args) {
var s1 = new Set();
s1.add('菠萝');
s1.add('苹果');
s1.add('苹果');
print(s1); //{菠萝, 苹果}
print(s1.toList()); //[菠萝, 苹果]
List l = ['香蕉', '葡萄', '葡萄', '白菜', '菠萝', '哈密瓜', '柚子'];
var s = new Set();
s.addAll(l);
print(s); //{香蕉, 葡萄, 白菜, 菠萝, 哈密瓜, 柚子}
print(s.toList()); //[香蕉, 葡萄, 白菜, 菠萝, 哈密瓜, 柚子]
}
7、map
映射(Maps)是无序的键值对
7.1 常用属性:
属性 | 描述 |
---|---|
keys | 获取所有的key值 |
values | 获取所有的value值 |
isEmpty | 是否为空 |
isNotEmpty | 是否不为空 |
7.2 常用方法:
方法 | 描述 |
---|---|
remove(key) | 删除指定key的数据 |
addAll({…}) | 合并映射 给映射内增加属性 |
containsKey | 查看映射内的属性 返回true/false |
containsValue | 查看映射内的值 返回true/false |
forEach | |
map | |
where | |
any | |
every |
import 'dart:collection';
void main(List<String> args) {
//声明方式
Map student = {
'name': 'codeSE',
'age': 20,
'isBoby': true,
};
print(student); //{name: codeSE, age: 20, isBoby: true}
var teacher = new Map();
teacher['name'] = 'Geen';
teacher['work'] = 'PC';
print(teacher); //{name: Geen, work: PC}
//常用方法
print(student.keys.toList()); //[name, age, isBoby]
print(student.values.toList()); //[name, age, isBoby]
print(student.isEmpty); //false
print(student.isNotEmpty); //true
student.addAll({
"grilFrinend": "ZXY",
"hoby": ['唱歌', '跳舞'],
"love me": true
});
student.remove("age");
print(
student); //{name: codeSE, isBoby: true, grilFrinend: ZXY, hoby: [唱歌, 跳舞], love me: true}
print(student.containsValue("codeSE")); //true
print(student.containsKey('name')); //true
teacher.forEach((key, value) {
print(key + "---" + value); //name---Geen work---PC
});
//循环三种方式
List color = ['red', 'blue', 'yellow'];
for (var i = 0; i < color.length; i++) {
print(color[i]);
}
for (var item in color) {
print(item);
}
color.forEach((item) {
print("${item}");
});
var nums = [45, 12, 33];
var newNums = [];
// List nums = [45, 12, 33];
// List newNums = new List();
for (var i = 0; i < nums.length; i++) {
newNums.add(nums[i] * 2);
}
print(newNums); //[90, 24, 66]
List list1 = [1, 3, 4];
var newList1 = list1.map((value) {
return value * 2;
});
print(newList1.toList()); //[2, 6, 8]
List list2 = [1, 3, 4, 5, 7, 8, 9];
var newList2 = list2.where((value) {
//任何满足条件
return value > 5;
});
print(newList2.toList()); //[7, 8, 9]
List list3 = [1, 3, 4, 5, 7, 8, 9];
var s = list3.any((value) {
//只要有满足条件的就返回true
return value > 5;
});
print(s); //true
List list4 = [1, 3, 4, 5, 7, 8, 9];
var f = list4.every((value) {
//每一个都满足条件返回true 否则返回false
return value > 5;
});
print(f); //false
}
8、函数(方法)
内置方法/函数:
print();
自定义方法:
自定义方法的基本格式 返回类型 方法名称(参数1,参数2,...){
方法体
return 返回值;
}
8.1 函数,方法定义、调用
void printInfo() {
print("自定义的函数/方法");
}
int getPrice() {
int price = 199;
return price;
}
String getName() {
return 'Jim Green';
}
List getColor() {
return ['red', 'blue', 'yellow'];
}
void main(List<String> args) {
print('这是系统内置的函数/方法');
printInfo();
var n = getPrice(); //自定义的函数/方法
print(n); //199
print(getName()); //Jim Green
print(getColor()); //[red, blue, yellow]
//函数作用域
void m() {
n() {
print('内部');
print(getName());
}
n();
}
// n();//错误
m();
}
8.2 可选参数、默认传参,函数参数
void main(List<String> args) {
int sum(int n) {
var m = 0;
for (var i = 0; i <= n; i++) {
m += i;
}
return m;
}
var s = sum(100);
print("总数为$s"); //5050
String userInfo(String name, int age, double kg) {
return '姓名:${name},年龄:$age,体重:$kg';
}
print(userInfo("小猪", 24, 52.2)); //姓名:小猪,年龄:24,体重:52.2
//默认参数用{}或者[]来声明,注意放在后面
String personInfo(String name, [double kg = 55.0, int age = 22]) {
return '姓名:${name},年龄:$age,体重:$kg';
}
print(personInfo("大明", 58)); //姓名:大明,年龄:22,体重:58.0
//函数当做参数
fun1() {
print('lxc is a boby');
}
fun2(fun) {
fun();
}
fun2(fun1); //lxc is a boby
}
8.3 箭头函数、函数相互调用
void main(List<String> args) {
List list1 = ['语文', '数学', '体育', '政治'];
list1.forEach((item) {
print(item);
});
//箭头函数=>
list1.forEach((item) => print(item));
//注意:箭头函数内只能写一条语句,且语句后面无(;)
//例1:修改数组的值,大于5的*2
List list2 = [2, 5, 6, 10, 600];
var newList2 = list2.map((item) {
if (item > 5) {
return item * 2;
}
return item;
});
//箭头函数=>
var newList3 = list2.map((e) => e > 5 ? e * 2 : e ,);
print(newList2.toList()); //[2, 5, 12, 20, 1200]
print(newList3.toList()); //[2, 5, 12, 20, 1200]
//例2:定义一个方法判断一个数大于10并且是否偶数
bool isValidity(int n) {
if (n > 10 && n % 2 == 0) {
return true;
}
return false;
}
//例3:打印上述满足条件的所有数
printNums(int n) {
for (var i = 0; i < n; i++) {
if (isValidity(i)) {
print('满足条件有:$i');
}
}
}
//调用
printNums(50);
}
8.4 匿名方法、自执行方法(js类似的立即执行函数)、递归方法
void main(List<String> args) {
//匿名方法
var getPrice = () {
print('普通函数匿名方法');
};
var setAge = (int n) => print('箭头函数匿名方法 $n');
getPrice();
setAge(20);
//自执行方法
(int a) {
print(a / 2); //15.0
print('自执行方法');
}(30);
//方法递归(注意:使用递归必须有终止条件,否则......)
var sum = 1;
fn(int n) {
sum *= n;
if (n == 1) {
return;
} else {
fn(n - 1);
}
}
fn(10);
print(sum); //3628800
}
8.4 闭包
闭包:
1、全局变量特点: 全局变量常驻内存、全局变量污染全局
2、局部变量的特点: 不常驻内存会被垃圾机制回收、不会污染全局
想实现的功能:(闭包可以解决)
1.常驻内存
2.不污染全局
闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包
/**全局变量 */
var n = 10;
void main() {
print(n); //10
f1() {
n++;
print(n);
}
f1(); //11
f1(); //12
f1(); //13
/**局部变量 */
printNum() {
var m = 100;
m++;
print(m);
}
printNum(); //101
printNum(); //101
printNum(); //101
//闭包
fn() {
var a = 123; //不污染全局 常驻内存
return () {
a++;
print(a);
};
}
var k = fn();
k(); //124
k(); //125
k(); //126
}