一、Dart介绍及环境
1.1 Dart介绍:
- Dart是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。
- Dart诞生于2011年,号称要取代JavaScript。但是过去的几年中一直不温不火。直到Flutter的出现现在被人们重新重视。 要学Flutter的话我们必须首先得会Dart。
- 官网:https://dart.dev/
1.2 Dart环境搭建:
- 要在我们本地开发Dart程序的话首先需要安装Dart Sdk
- 官方文档:Get the Dart SDK | Dart
- windows(推荐): Dart for Windows
- mac:如果mac电脑没有安装brew这个工具首先第一步需要安装它: https://brew.sh/
brew tap dart-lang/dart
brew install dart
1.3 Dart 开发工具:
- Dart的开发工具有很多: IntelliJ IDEA 、 WebStorm、 Atom、Vscode等
- 这里我们主要给大家讲解的是如果在VSCode中配置Dart。
1、找到vscode插件安装dart
2、找到vscode插件安装code runner ; Code Runner 可以运行我们的文件
1.4 Hello Dart
- 使用VSCode,新建文件夹及Dart文件,运行输出(快捷键: Control+Option+N)
main() {
print("Hello World");
}
二、Dart常量、变量、命名规则
2.1 Dart 变量:
- dart是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推倒
- dart中定义变量可以通过var关键字可以通过类型来申明变量
如:
var str = 'this is var';
String str = 'this is var';
int str = 123;
- 注意: var 后就不要写类型 ,写了类型不要var 两者都写 var a int = 5; 报错
2.2 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
2.3 Dart的命名规则:
1.变量名称必须由数字、字母、下划线和美元符($)组成。
2.注意:标识符开头不能是数字
3.标识符不能是保留字和关键字。
4.变量的名字是区分大小写的如: age和Age是不同的变量。在实际的运用中,也建议,不要用一个单词大小写区分两个变量。
5、标识符(变量名称)一定要见名思意 :变量名称建议用名词,方法名称建议用动词
三、Dart数据类型
3.1 Dart中支持以下数据类型:
- 常用数据类型:
- Numbers(数值): int、double
- Strings(字符串): String
- Booleans(布尔): bool
- List(数组): 在Dart中,数组是列表对象,所以大多数人只是称它们为列表
//1、第一种定义List的方式
var l1=["张三",20,true];
print(l1); //[张三, 20, true]
print(l1.length); //3
print(l1[0]); //张三
print(l1[1]); //20
//2、第二种定义List的方式 指定类型
var l2=<String>["张三","李四"];
print(l2);
var l3 = <int>[12, 30];
print(l3);
//3、第三种定义List的方式 增加数据 ,通过[]创建的集合它的容量可以变化
var l4 = [];
print(l4);
print(l4.length);
l4.add("张三");
l4.add("李四");
l4.add(20);
print(l4);
print(l4.length);
var l5 = ["张三", 20, true];
l5.add("李四");
l5.add("zhaosi");
print(l5);
// 4、第四种定义List的方式
// var l6=new List(); //在新版本的dart里面没法使用这个方法了
var l6=List.filled(2, ""); //创建一个固定长度的集合
print(l6);
print(l6[0]);
l6[0]="张三"; //修改集合的内容
l6[1]="李四";
print(l6); //[张三, 李四]
l6.add("王五"); //错误写法 通过List.filled创建的集合长度是固定 没法增加数据
//通过List.filled创建的集合长度是固定
var l7 =List.filled(2, "");
print(l7.length);
l7.length=0; //修改集合的长度 报错
var l8=<String>["张三","李四"];
print(l8.length); //2
l8.length=0; //可以改变的
print(l8); //[]
var l9=List<String>.filled(2, "");
l9[0]="string";
// l8[0]=222;
print(l9);
-
-
- 1、字面量定义List
- 2、指定类型定义List
- 3、通过[]创建的集合它的容量可以可以变化,增加数据
- 4、创建一个固定长度的集合 List.filled(2, "")
-
-
- Maps(字典): 通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个键只出现一次,而一个值则可以出现多次
void main(){
//第一种定义 Maps的方式
var person={
"name":"张三",
"age":20,
"work":["程序员","送外卖"]
};
print(person);
print(person["name"]);
print(person["age"]);
print(person["work"]);
//第二种定义 Maps的方式
var p=new Map();
p["name"]="李四";
p["age"]=22;
p["work"]=["程序员","送外卖"];
print(p);
print(p["age"]);
}
-
-
- 1、字面量定义Maps
- 2、创建空的Map(),Key Value形式增加数据
-
- 项目中用不到的数据类型 (用不到):
- Runes
- Rune是UTF-32编码的字符串。它可以通过文字转换成符号表情或者代表特定的文字。
- Runes
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非常有用,因为缩小会更改标识符名称而不会更改标识符符号。要获取标识符的符号,请使用符号文字,它只是#后跟标识符:
- Symbols
- 在 Dart 中符号用 # 开头来表示,入门阶段不需要了解这东西,可能永远也用不上。
3.2 Dart类型判断
Dart中用 is 关键词来判断类型
void main(){
var str='1234';
if(str is String){
print('是string类型');
}else if(str is int){
print('int');
}else{
print('其他类型');
}
}
四、Dart运算符、条件判断、类型转换
4.1 Dart运算符:
- 算术运算符
- + - * / ~/ (取整) %(取余)
- 关系运算符
- == != > < >=
- 逻辑运算符
- ! && ||
- 赋值运算符
- 基础赋值运算符 = ??=
int b = 6;
b??=23; 表示如果b为空的话把 23赋值给b
-
- 复合赋值运算符 += -= *= /= %= ~/=
// ~/= 取整等于
var num = 16;
num ~/= 5;
print(num);
- 条件表达式
- if else; switch case
- 三目运算符
- ??运算符:
4.2 类型转换
- 1、Number与String类型之间的转换
- Number类型转换成String类型 toString()
- String类型转成Number类型 int.parse()
String str='123';
var myNum1=int.parse(str);
print(myNum1); //123
print(myNum1 is int);//true
String str2='123.1';
var myNum2=double.parse(str2);
print(myNum2); //123.1
print(myNum2 is double); // true
-
- 可以采用try ...catch,防止发生问题
// try ... catch
String price='';
try{
var myNum=double.parse(price);
print(myNum);
}catch(err){
print(0);
}
- 2、其他类型转换成Booleans类型
- isEmpty:判断字符串是否为空
- == 0: 判断是否为0
- == null: 判空
- isNaN: 判断非数字值
五、Dart循环语句、for循环、do-while循环、break和continue
5.1 ++、--
- 在赋值运算里面,如果++ -- 写在前面;这时候先运算再赋值,如果++ --写在后面:先赋值后运行运算
var a1=10;
var b1=a1++;
print(a1); //11
print(b1); //10
var a2=10;
var b2=++a2;
print(a2); //11
print(b2); //11
5.2 for 循环
- 定义一个二维数组 打印里面的内容
List list=[
{
"cate":'国内',
"news":[
{"title":"国内新闻1"},
{"title":"国内新闻2"},
{"title":"国内新闻3"}
]
},
{
"cate":'国际',
"news":[
{"title":"国际新闻1"},
{"title":"国际新闻2"},
{"title":"国际新闻3"}
]
}
];
- for循环使用
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"]);
}
}
5.3 while循环/ do-while循环
while(表达式/循环条件){
}
do{
语句/循环体
}while(表达式/循环条件);
注意: 1、最后的分号不要忘记
2、循环条件中使用的变量需要经过初始化
3、循环体中,应有结束循环的条件,否则会造成死循环。
var j=10;
do{
print('执行代码');
}while(j<2);
5.4 break和continue
- break语句功能:
1、在switch语句中使流程跳出switch结构。
2、在循环语句中使流程跳出当前循环,遇到break 循环终止,后面代码也不会执行
-
- 强调:
1、如果在循环中已经执行了break语句,就不会执行循环体中位于break后的语句。
2、在多层循环中,一个break语句只能向外跳出一层
-
- break可以用在switch case中 也可以用在 for 循环和 while循环中
var sex="男";
switch (sex) {
case "男":
print('男');
break;
case "女":
print('男');
break;
default:
}
- continue语句的功能:
- 【注】只能在循环语句中使用,使本次循环结束,即跳过循环体重下面尚未执行的语句,接着进行下次的是否执行循环的判断。
- continue可以用在for循环以及 while循环中,但是不建议用在while循环中,一不小心容易死循环
for(var i=1;i<=10;i++){
if(i==4){
continue; /*跳过当前循环体 然后循环还会继续执行*/
}
print(i);
}
- 六、Dart中List、Set、Map、forEach/map/where/any/every
6.1 List里面常用的属性和方法:
- 常用属性:
length 长度
reversed 翻转
isEmpty 是否为空
isNotEmpty 是否不为空
- 常用方法:
add 增加
addAll 拼接数组
indexOf 查找 传入具体值
remove 删除 传入具体值
removeAt 删除 传入索引值
fillRange(start,end,[fillValue]) 修改 ,从start索引开始,到end索引结束,填充[fillValue]中的值, 不包含end索引.
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
toList() 其他类型转换成List
join(String) List通过括号中的String拼接成字符串
split(String) 字符串通过(String)拆分成List
forEach 循环遍历的简写
map 根据条件对原始数据进行修改并返回
where 根据给定限定条件进行过滤
any 只要集合里面有满足条件的就返回true
every 每一个都满足条件返回true,否则返回false
//fillRange的使用
List myList=['香蕉','苹果','西瓜'];
myList.fillRange(1, 2,'aaa'); //修改
print(myList);//[香蕉, aaa, 西瓜]
myList.fillRange(1, 3,'aaa');
print(myList);//[香蕉, aaa, aaa]
//insert的使用
myList.insert(1,'aaa'); //插入 一个
print(myList);//[香蕉, aaa, aaa, aaa]
myList.insertAll(1, ['aaa','bbb']); //插入 多个
print(myList);//[香蕉, aaa, bbb, aaa, aaa, aaa]
- 根据众多语法的相通性. 这里forEach、map、where、any、every的理解相对容易,只不过是换了个名字.
//1. forEach遍历
List myList=['香蕉','苹果','西瓜'];
myList.forEach((value){
print("$value");
});
//2.map 根据条件对List进行修改
List myListMap=[1,3,4];
var mapList=myListMap.map((value){
return value*2;
});
print(mapList.toList()); //[2, 6, 8]
//3.where: 根据给定限定条件,过滤
List whereList=[1,3,4,5,7,8,9];
var newList=whereList.where((value){
return value>5;
});
print(newList.toList());//[7, 8, 9]
//4.any: 只要集合里面有满足条件的就返回true
List anyList=[1,3,4,5,7,8,9];
var anyValue=anyList.any((value){ //只要集合里面有满足条件的就返回true
return value>5;
});
print(anyValue);
//5.every: 每一个都满足条件返回true 否则返回false
List myList=[1,3,4,5,7,8,9];
var everyValue=myList.every((value){ //每一个都满足条件返回true 否则返回false
return value>5;
});
print(everyValue);
6.2 Set
- 用它最主要的功能就是去除数组重复内容
- Set是没有顺序且不能重复的集合,所以不能通过索引去获取值
var s1=new Set();
s1.add('香蕉');
s1.add('苹果');
s1.add('苹果');
print(s1); //{香蕉, 苹果}
print(s1.toList()); //[香蕉, 苹果]
List myList=['香蕉','苹果','西瓜','香蕉','苹果','香蕉','苹果'];
var s2=new Set();
s2.addAll(myList);
print(s2); //{香蕉, 苹果, 西瓜}
print(s2.toList()); //[香蕉, 苹果, 西瓜]
s2.forEach((value)=>print(value)));
6.3 Map
- 字典结构在forEach时,遍历key-value
Map person={
"name":"张三",
"age":20
};
person.forEach((key,value){
print("$key---$value");
});
/*
name---张三
age---20
*/
七、函数的定义、可选参数、默认参数、命名参数
7.1 内置方法/函数
-
- 例如: print();
7.2 自定义方法:
-
- 自定义方法的基本格式:
返回类型 方法名称(参数1,参数2,...){
方法体
return 返回值;
}
- 自定义一些方法
void printInfo() {
print('一个自定义方法');
}
int getNumber(){
var myNumber = 123;
return myNumber;
}
String printUserInfo(){
return 'this is string';
}
List getList(){
return ['121','123','125'];
}
-
- 调用自定义方法
printInfo();
var n = getNumber();
print(n);
print(printUserInfo());
print(getList());
7.3 方法的作用域
- 在方法A内部可以再定义方法B,但是B方法只能在方法A作用域内使用
void aMethod(){
aaa(){
print(getList());
print('aaa');
}
aaa();
}
//调用方法
aMethod();
7.4 调用方法传参
7.4.1、定义一个方法 求1到这个数的所有数的和
int sumNum(int num){
var sum = 0;
for(var i = 1;i <= n;i++){
sum += i;
}
return sum;
}
var n1 = sumNum(5);
print(n1);
var n2 = sumNum(100);
print(n2);
7.4.2 定义一个方法然后打印用户信息
String printUserInfo(String username, int age){
//行参
return "姓名: $username --- 年龄: $age";
}
print(printUserInfo("张三",20));//实参
7.4.3 定义一个带可选参数的方法
- 最新的dart定义可选参数需要指定类型默认值
- [int age] 表示age为可选参数
String printUserInfo(String username, [int age = 0]){//行参
if (age != 0){
return "姓名:$username --- 年龄: $age";
}
return "姓名:$username --- 年龄保密";
}
print(printUserInfo("李四",28));
print(printUserInfo("王五"));
7.4.4 定义一个带默认参数的方法
- 在可选参数列表中,对参数进行初始化赋值.
String printUserInfo(String username,[String sex="男",int age=0]){//行参
if (age != 0){
return "姓名:$username --- 性别:$sex --- 年龄:$age";
}
return "姓名:$username --- 性别: $sex --- 年龄保密";
}
print(printUserInfo("张三"));
print(printUserInfo("莉丝","女"));
print(printUserInfo("莉丝","女", 26));
7.4.5 定义一个命名参数的方法
- 最新的dart定义命名参数需要指定类型默认值
String printUserInfo(String username,{int age = 0,String sex = '男'}){//行参
if (age != 0){
return "姓名:$username --- 性别: $sex --- 年龄: $age";
}
return "姓名:$username --- 性别: $sex --- 年龄保密";
}
print(printUserInfo("钩陈",age: 20, sex: '未知'));
7.4.6 实现一个把方法当作参数的方法
- 调用fn2这个方法,把fn1这个方法当作参数传入.
var func=() {
print("我是一个匿名方法");
};
func();
//fn1方法
fn1(){
print("function one");
}
//fn2方法
fn2(func){
func();
}
//调用fn2这个方法,把fn1这个方法当作参数传入.
fn2(fn1);
-
- 调用结果
我是一个匿名方法
fn1
八、箭头函数、匿名方法、闭包
8.1 箭头函数
- 箭头函数是一种缩写形式
案例1:
List list=['苹果','香蕉','西瓜'];
list.forEach((value){
print(value);
});
list.forEach((value)=>print(value));
- 注意和方法的区别: 箭头函数内只能写一条语句,并且语句后面没有分号(;)
list.forEach((value)=>{
print(value)
});
案例2: 修改下面List里面的数据,让数组中大于2的值乘以2
List list1 = [4,1,2,3,4];
var mapList1 = list1.map((value){
if (value > 2){
return value * 2;
}
return value;
});
print(mapList1.toList()); //[8, 1, 2, 6, 8]
var mapList2=list1.map((value)=> value > 2 ? value*2:value);
print(mapList2.toList());//[8, 1, 2, 6, 8]
案例3:
- 1、定义一个方法isEvenNumber来判断一个数是否是偶数.
//1、定义一个方法isEvenNumber来判断一个数是否是偶数
bool isEvenNumber(int n){
if (n % 2 == 0) {
return true;
}
return false;
}
- 2、定义一个方法打印1-n以内的所有偶数.
printNum(int n){
for (var i = 1; i <= n; i++){
if (isEvenNumber(i)) {
print(i);
}
}
}
printNum(10);
8.2 匿名函数&自执行方法&方法的递归
- 首先定义一个获取整型数的方法
int getNum(int n){
return n;
}
print(getNum(12));
8.2.1 匿名函数
- 形如 (){}; 的函数
var printNumber = () {
print(12345);
};
printNumber();
8.2.2 自执行方法
((int n){
print(n*2);
print("这是自执行方法");
})(123);
8.2.3 方法的递归
var suma = 1;
fua(int n){
suma *= n;
if (n == 1) {
return;
}
fna(n - 1);
}
fna(5);
print(suma);//1*2*3*4*5 = 120
案例4: 通过方法的递归,求1-100的和
var sum = 0;
fn(int n){
sum += n;
if (n == 0) {
return;
}
fn(n-1);
}
fn(100);
print(sum);//5050
8.3 闭包
8.3.1 闭包的由来
- 1、全局变量特点: 全局变量常驻内存、全局变量污染全局.
- 2、局部变量的特点: 不常驻内存会被垃圾机制回收、不会污染全局.
- 想实现的功能:
1.常驻内存
2.不污染全局
- 因此产生了闭包,闭包可以解决这个问题.....
- 闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
- 闭包的写法:函数嵌套函数,并return 里面的函数,这样就形成了闭包。
8.3.2 全局变量
var a = 123;
void main(){
print(a);
func(){
a++;
print(a);
}
func();//124
func();//125
func();//126
}
8.3.3 局部变量文章来源:https://www.toymoban.com/news/detail-437647.html
printInfo(){
var myNum = 234;
myNum++;
print(myNum);
}
printInfo();//235
printInfo();//235
printInfo();//235
8.3.4 闭包文章来源地址https://www.toymoban.com/news/detail-437647.html
funcClosure(){
var a = 345;//不会污染全局,常驻内存
return (){
a++;
print(a);
};
}
var para = funcClosure();
para();//346
para();//347
para();//348
到了这里,关于Dart语法上的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!