Flutter框架之Dart语言——1.SDK环境配置-数据类型-运算符-分支循环语句-异常处理

  • 工具:要让 Flutter 在你的开发环境中正常使用,依赖于以下的工具:

    • Windows PowerShell 5.0 或者更高的版本(Windows 10 中已预装)

    • Git for Windows 2.x,并且勾选从 Windows 命令提示符使用 Git 选项。

      如果 Windows 版的 Git 已经安装过了,那么请确保能从命令提示符或者 PowerShell 中直接执行 git 命令。D:\Program Files\flutter\bin

一、入门

1.配置

1)Flutter SDK

  1. 点击下方的安装包,获取 stable 发行通道的 Flutter SDK 最新版本:

    https://flutter.cn/docs/get-started/install/windows#

    要查看其他发行通道和以往的版本,请参阅 SDK 版本列表 页面。

  2. 将压缩包解压,然后把其中的 flutter 目录整个放在你想放置 Flutter SDK 的路径中(例如 C:\src\flutter)。

请注意

请勿将 Flutter 有特殊字符或空格的路径下。

请注意

请勿将 Flutter 安装在需要高权限的文件夹内,例如 C:\Program Files\

现在你可以在控制台当中使用 Flutter 的命令了。

2)更新 path

如果你想在 Windows 控制台中运行 Flutter 命令,需要按照下面的步骤来将 Flutter 的运行文件路径加入到 PATH 环境变量。

  • 在开始菜单的搜索功能键入「env」,然后选择 编辑系统环境变量
  • 用户变量 一栏中,检查是否有 Path 这个条目:
    • 如果存在这个条目,以 ; 分隔已有的内容,加入 flutter\bin 目录的完整路径。
    • 如果不存在的话,在用户环境变量中创建一个新的 Path 变量,然后将 flutter\bin 所在的完整路径作为新变量的值。

你需要重新打开已经打开的命令行提示符窗口,这样下次启动命令提示符时,才能访问到刚才修改的变量。

提示

自 Flutter 1.19.0 dev 版本开始,Flutter SDK 在 flutter 命令脚本的同级目录下增加了 dart 命令,你可以更方便地运行 Dart 命令行程序。下载 Flutter SDK 时也会下载对应版本的 Dart SDK,但如果你单独下载了 Dart SDK,请确保 Flutter SDK 内的 dart 在你的环境变量中排在首位,因为单独的 SDK 可能并不兼容 Flutter SDK。下面的命令展示了 flutterdart 是否来自相同的 bin 目录,并且是否可以兼容使用。

  C:\>where flutter dart
  C:\path-to-flutter-sdk\bin\flutter
  C:\path-to-flutter-sdk\bin\flutter.bat
  C:\path-to-dart-sdk\bin\dart.exe        :: this should go after `C:\path-to-flutter-sdk\bin\` commands
  C:\path-to-flutter-sdk\bin\dart
  C:\path-to-flutter-sdk\bin\dart.bat

如上所示,Flutter SDK 内的 dart 命令不在首位。你需要更新 PATH,将 C:\path-to-flutter-sdk\bin\ 放在 C:\path-to-dart-sdk\bin\ 前面(当前场景)。接着重启命令行使修改生效,再次运行 where,此时来自相同目录的 flutterdart 已经排在前面。

  C:\>where flutter dart
  C:\dev\src\flutter\bin\flutter
  C:\dev\src\flutter\bin\flutter.bat
  C:\dev\src\flutter\bin\dart
  C:\dev\src\flutter\bin\dart.bat
  C:\dev\src\dart-sdk\bin\dart.exe

然而,如果你在使用 PowerShellwhere 其实是 Where-Object 命令的别名,所以实际上你需要运行 where.exe

  PS C:\> where.exe flutter dart

了解更多 dart 命令的用法,可以在命令行中运行 dart -h 查看,也可以访问 DartVM 运行环境

Android Studio 的 Flutter 或者 Dart 插件安装

2.基础语法

1)入口方法

main(){
	print('hello dart');
}

// void代表没有返回值
void main(){
	print('hello dart');
}

2)注释

// 单行注释

/*
多行注释
*/

/**
文档注释
*/

/// 使用三个斜杠开头
///这是Dart特有的文档注释

3.Dart命名规则

1)变量名称必须有数字,字母,下划线,和美元符号($)组成

2)标识符的开头不能是数字开头

3)标识符不能使用关键字和保留字

4)变量的名称是会区分大小写的

5)定义标识符的时候意思要尽量明朗,通常变量的名称使用名词,方法的名称使用动词

4.Dart变量

Dart中定义变量有两种方式,一种是静态类型语言常用的方式,显式指定变量类型,另一种则是动态语言的常用方式,不指定类型,由vm自动推断。可通过var关键字声明变量,也可通过显式类型声明

// 1.通过显式指定类型来定义变量
String name ="张三";
num age = 18;

// 2.使用关键字var,不指定类型
var address ="深南大道";
var id = 100;

/*
使用var定义变量,即使未显式指定类型,一旦赋值后类型就被固定因此使用var定义的变量不能改变数据类型
*/
var number = 19;

// 以下代码错误,无法运行,number变量已确定为int类型
number = "2019"

注意: var关键字和具体类型不要同时写,如:var int str =123; 报错

如想动态改变变量的数据类型,应当使用dynamicObject来定义变量。

// dynamic声明变量
dynamic varl = "hello";
var1 = 19;
print(var1);
// 19

// object声明变量
Object var2 = 20;
var2 ="Alice";
print(var2);
// Alice

5.Dart常量

Dart的常量使用final和const修饰

  • const修饰的常量在一开始的时候就需要赋值(编译的时候就已经赋好值了)
  • final修饰的常量可以在一开始的时候不赋值,但同样只能赋值一次(惰性赋值,运行时第一次使用时赋值)
// const常量
const PI = 3.14159;
PI = 3//错误,常量的值不能修改
// final常量
final a = new DateTime.now();     //给a运行时赋值

需要注意,final定义的常量是运行时常量,而const常量则是编译时常量,也就是说final定义常量时,其值可以是一个变量,而const定义的常量,其值必须是一个字面常量值。

final time = new DateTime.now(); // 正确
const time = new DateTime.now(); // 错误

const list = const[1,2,3];     // 正确
const list = [1,2,3];          // 错误

二、数据类型

1.基本类型

请添加图片描述

常用的数据类型:

  • Numbers(数值):int,double
  • Strings(字符串) : String
  • Booleans(布尔) : bool
  • List(数组) : 在Dart中数组是列表对象
  • Maps(字典) : Map为键值对相关对象

在Dart中,所有能够使用变量引用的都是对象,每个对象都是一个类的实例。数字、函数和 null 也都是对象。所有的对象都继承于Object类。要注意,没有初始化的变量默认值为 null。数值类型变量的默认值也是 null。

1)数值类型

数值类型num有两个具体子类,分别为int和double,其中int为整数值,范围是-253至253之间;double则是64位的双精度浮点数。

int 整型
int a = 1;
var a = 1;
int a = 1.4;  // 报错

指明数据类型则变量不为空

int a=123;  //非空的int类型
a=null;  //A value of type 'Null' can't be assigned to a variable of type 'int'
double 浮点型
double b = 2.5;
double b = 2 ;    // 给浮点型变量赋值整型不会报错,但输出的结果会自动补小数点后的0

2)字符串类型

可以用单引号,也可以用双引号

var str1 = ' i am str1';String str1 = ' i am str1';

var str2 = "i am str2";String str2 = "i am str2";

使用三引号定义字符串可以换行

String str3='''
i am str1
i am str2
i am str3''';

或:
String str3="""
i am str1
i am str2
i am str3""";

字符串拼接

// 方式一
print("$str1 $str2");
// 方式二
print(str1 + " " + str2);

指明数据类型则变量不为空

String username="张三";  //非空的String类型
username=null;   //A value of type 'Null' can't be assigned to a variable of type 'String'.

Dart中提供的字符串插值表达式使字符串格式化方便

// 1.Dart可以使用单引号或双引号来创建字符串
var sl = "hello";
var s2 = 'world' :

// 2.类似Python,Dart可以使用三引号来创建包含多行的字符串
var multiLinel ="""你可以像这样,创建
一个包含了多行的字符串内容"""
var multiLine2 = '''你也可以使用三个单引号,创建一个
包含了多行的字符串内容'''
    
//3.类似Python,还可以在字符串字面值的前面加上广来创建原始字符串,则该字符串中特殊字符可以不用转义
var path = r'D: wo rkspace  code';

// 4.Dart支持使用"+”操作符拼接字符串
var greet = "hello" +" world":

// 5.Dart提供了插值表达式"$tJ",也可以用于拼接字符串
var name ="王五";
var astr = "hello, ${name}";
print(aStr);
// hello,王五

//当仅取变量值时,可以省略花括号
var astr2 = "hello,$name"; 
// hello,王五

//当拼接的是一个表达式时,则不能省略花括号
var strl ="ink":
var str2 = "click fstrl.toUpperCase()}";
print(str2);
// click LINK

// 6.与Java不同,Dart使用"=="来比较字符串的内容
print("hello" == "world"):

3)布尔类型

Dart中的布尔类型用法同Java,仅有falsetrue两个值,不能使用 0、非 0 或者null、非null来表达falsetrue。与Java不同的是,布尔类型的默认值为null

bool b1 = true;
bool b2 = false;
bool flags;
print(flags); // n
ull

2.List类型

1)定义

Dart数据类型: List(数组/集合)
1、第一种定义List的方式

var l1 = ["张三", 20, true];
print(l1); //[张三, 20, true]
print(l1.length); //3
print(l1[0]); //张三
print(l1[1]); //20

var list = [1,2,3];
// 下标从0开始。使用length可以访问list的长度
print(list[0]);

// 可在List字面量前添加const关键字,定义一个不可改变的 列表(编译时常量)
var constantList = const [1, 23];
constantList[1] = 1;  // 报错
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 l6 = List.<String>filled(2, "");
  print(l6.length);
  l6.length = 0; //修改集合的长度   报错

指明数据类型则变量不为空

List<String> l1 = ["张三", "李四", "王五"];
l1 =
    null; //A value of type 'Null' can't be assigned to a variable of type 'List<String>'.

2)属性

常用属性:
length          长度
reversed        翻转
isEmpty         是否为空
isNotEmpty      是否不为空
List myList=['香蕉','苹果','西瓜'];
// List myList=['香蕉','苹果','西瓜']; 不可重新赋值

// List里面的属性:
print(myList.length);
// 3
print(myList.isEmpty);
// false
print(myList.isNotEmpty);
// true
print(myList.reversed);  //对列表倒序排序
// (西瓜, 苹果, 香蕉)
var newMyList=myList.reversed.toList();  
print(newMyList);
// [西瓜, 苹果, 香蕉]

3)方法

方法名作用
cast将一个数组的类型传递给未指定数据类型的数组
List.generate快速生产 Flutter 中的 Widget
reduce用指定的函数方式对数组中的所有元素做连续操作,并将结果返回
fold根据一个现有数组和一个初始参数值 initValue,指定参数条件操作现有数组的所有元素,并返回处理的结果
expand根据现有数组,指定一个处理方式,返回一个 Iterable
// cast 将一个数组的类型传递给未指定数据类型的数组

List<int> l1 = [8, 12, 8];
var l2 = l1.cast(); // 指定 l2 的数据类型和 l1 的一样,都是 int 类型
l2.add(6);
print(l1); // [8, 12, 8, 6]
l2.add("ddd");
print(l1); // 报错,提示无法将 String 类型的数添加到 int 类型的数组中
// List.generate 快速生产 Flutter 中的 Widget

List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
...
children: List.generate(l1.length, (index){
return Text("$index");
})
// reduce 用指定的函数方式对数组中的所有元素做连续操作,并将结果返回

List<int> l1 = [1, 2, 3, 4];
int res1 = l1.reduce((a, b) => (a * b)); // 元素依次相乘
int res2 = l1.reduce((a, b) => (a + b)); // 元素依次相加
print(res1); // 1*2*3*4 = 24
print(res2); // 1+2+3+4 = 10
// fold 根据一个现有数组和一个初始参数值 initValue,指定参数条件操作现有数组的所有元素,并返回处理的结果

List<int> l1 = [1, 2, 3, 4];
// 2 为初始参数值,后面定义的方法为该初始值和原数组之间的处理方式
int res1 = l1.fold(2, (a, b) => (a * b)); // 相乘
int res2 = l1.fold(2, (a, b) => (a + b)); // 相加
print(res1); // 2*(1*2*3*4) = 48
print(res2); // 2+(1+2+3+4) = 12
// expand 根据现有数组,指定一个处理方式,返回一个 Iterable

List<int> l1 = [1, 2, 3, 4];
// 将 l1 数组内的每一个元素都和指定的表达式组相操作
Iterable<int> l2 = l1.expand((e) => [e + 1]);
Iterable<int> l3 = l1.expand((e) => [e + 1, e + 2]);
Iterable<int> l4 = l1.expand((e) => [e + 2, e * 2]);
Iterable<num> l5 = l1.expand((e) => [e * 2, e / 2]);
Iterable<int> l6 = l1.expand((e) => [e, e + 1, e + 2]);
print(l2); // (2, 3, 4, 5)
print(l3); // (2, 3, 3, 4, 4, 5, 5, 6)
print(l4); // (3, 2, 4, 4, 5, 6, 6, 8)
print(l5); // (2, 0.5, 4, 1.0, 6, 1.5, 8, 2.0)
print(l6); // (1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6)

"添加"数据的方法

方法名作用
add添加一个元素到数组末尾
addAll合并两个数组
insert在指定索引处插入一个值
insertAll在指定索引处插入一个数组
// add 添加一个元素到数组末尾

List<String> l1 = ["周一", "周二", "周三"];
l1.add("周四");
l1.add("周五");
print(l1); 
// [周一, 周二, 周三, 周四, 周五]

// 需要注意的是,你不能向一个固定长度的数组用 add() 方法添加元素,否则会抛出异常
List<String> l2 = List(1);
l2.add("Allen Su");
// addAll 合并两个数组

List<String> l1 = ["周一", "周二", "周三"];
List<String> l2 = ["周四", "周五", "周六","周日"];
l1.addAll(l2);
print(l1); 
// [周一, 周二, 周三, 周四, 周五, 周六, 周日]

// 因为 List 和 Set 都继承于 Iterable,所以 List 可以直接当 addAll() 方法的参数使用。需要注意的是,你不能向一个固定长度的数组用 addAll() 方法添加元素,否则会抛出异常,如下代码所示
List<String> l4 = List(1);
l4.addAll(["Allen Su"]);
print(l4);
// insert 在指定索引处插入一个值

List<String> l1 = ["周一", "周二", "周三"];
l1.insert(3, "周四");
print(l1); 
// [周一, 周二, 周三, 周四]
l1.insert(0, "周日");
print(l1); 
// [周日, 周一, 周二, 周三, 周四]
// insertAll 在指定索引处插入一个数组

List<String> l1 = ["周一", "周二", "周三"];
List<String> l2 = ["周四", "周五", "周六", "周日"];
l1.insertAll(0, l2);
print(l1); 
// [周四, 周五, 周六, 周日, 周一, 周二, 周三]
  • 如果数组中有该数据或者满足删除的条件,则删除,原数组发生改动。
  • 如果要删除的数据不在数组中,或者删除元素的条件不成立,也不会报错,返回原数组。
方法名作用
remove删除指定元素
removeAt删除指定索引位置处的元素
removeLast删除数组的最后一个元素
clear清空数组
removeWhere根据指定条件删除元素
removeRange删除指定索引范围内的元素(含头不含尾)
// remove 删除指定元素 查看更多

List<String> l1 = ["周一", "周二", "周三","周一"];
l1.remove("周一");
print(l1); // [周二, 周三, 周一]
// removeAt 删除指定索引位置处的元素 

List<String> l1 = ["周一", "周二", "周三"];
l1.removeAt(0);
print(l1); // [周二, 周三]
// removeLast 删除数组的最后一个元素

List<String> l1 = ["周一", "周二", "周三"];
l1.removeLast();
print(l1); // [周一, 周二]
// clear 清空数组

List<String> l1 = ["周一", "周二", "周三"];
l1.clear();
print(l1); // []
// removeWhere 根据指定条件删除元素

List<String> l1 = ["周一", "周二", "周三"];
l1.removeWhere((e) => e == "周二");
print(l1); // [周一, 周三]

List<String> l2 = ["周一", "周二", "周三","星期四"];
l2.removeWhere((e) => e.contains("周"));
print(l2); // [星期四]
// removeRange 删除指定索引范围内的元素(含头不含尾) 

List<String> l1 = ["周一", "周二", "周三","周四", "周五", "周六", "周日"];
l1.removeRange(2, 5);
print(l1); // [周一, 周二, 周六, 周日]
方法名作用
List [index]修改指定索引位置元素的值
toSet将 List 转换为 Set,得到去重后的元素
asMap将 List 转换为 Map,key 为原数组的索引,value 为原数组的元素
sort数组排序(原数组发生改变)
shuffle随机排列指定数组(修改了原数组)
join用指定字符连接数组中每个元素,返回 String
fillRange用相同的值替换指定索引范围内的所有元素(含头不含尾)
replaceRange用某一数组替换指定索引范围内的所有元素(含头不含尾)
setRange范围替换数组中的值(含头不含尾)
setAll从指定索引位置开始,使用第二个数组内的元素依次替换掉第一个数组中的元素
// List [index] 修改指定索引位置元素的值

List<String> l1 = ["周一", "周二", "周三", "星期四"];
l1[3] = "周四";
print(l1); // [周一, 周二, 周三, 周四]
// toSet 将 List 转换为 Set,得到去重后的元素

List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
Set<int> l2 = l1.toSet();
print(l2);
// {8, 12, 6, 22, 10}
// asMap 将 List 转换为 Map,key 为原数组的索引,value 为原数组的元素

List<String> l1 = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
Map map = l1.asMap();
print(map); // {0: 周一, 1: 周二, 2: 周三, 3: 周四, 4: 周五, 5: 周六, 6: 周日}
// sort 数组排序(原数组发生改变)

List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
l1.sort();
List<String> l2 = ["f", "d", "b", "c", "a", "e"];
l2.sort();
print(l1); // [6, 8, 8, 10, 12, 12, 22]
print(l2); // [a, b, c, d, e, f] 
// shuffle 随机排列指定数组(修改了原数组)

List<int> l1 = [1, 2, 3, 4];
l1.shuffle();
print(l1); // [1, 4, 2, 3]
l1.shuffle();
print(l1); // [2, 1, 3, 4]
// join 用指定字符连接数组中每个元素,返回 String

List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
String str1 = l1.join();
String str2 = l1.join("");
String str3 = l1.join(" ");
String str4 = l1.join(",");
String str5 = l1.join("-");
print(str1); // 81286221210
print(str2); // 81286221210
print(str3); // 8 12 8 6 22 12 10
print(str4); // 8,12,8,6,22,12,10
print(str5); // 8-12-8-6-22-12-10
// fillRange 用相同的值替换指定索引范围内的所有元素(含头不含尾)

List<String> l1 = ["周一", "周二", "周三", "周四", "周五"];
l1.fillRange(1, 4, "AllenSu");
print(l1); // [周一, AllenSu, AllenSu, AllenSu, 周五]
// replaceRange 用某一数组替换指定索引范围内的所有元素(含头不含尾)

List<String> l1 = ["周一", "周二", "周三"];
l1.replaceRange(1, 2, ["周四", "周五", "周六", "周日"]);
print(l1); // [周一, 周四, 周五, 周六, 周日, 周三]

List<String> l2 = ["周一", "周二", "周三", "周四", "周五"];
l2.replaceRange(0, 4, ["周六", "周日"]);
print(l2); // [周六, 周日, 周五]
// setRange 范围替换数组中的值(含头不含尾)

List<String> l1 = ["11", "22", "33"];
List<String> l2 = ["aa", "bb", "cc"];
l1.setRange(0, 2, l2); // 用 l2 数组中索引为 0 1 位置处元素的值,替换掉 l1 数组中索引 0 1 位置处元素的值
print(l1); // [aa, bb, 33]
// setAll 从指定索引位置开始,使用第二个数组内的元素依次替换掉第一个数组中的元素

List<String> l1 = ["周一", "周二", "周三", "周四"];
List<String> l2 = ["周五", "周六", "周日"];
l1.setAll(1, l2);
print(l1); // [周一, 周五, 周六, 周日]

// 注意: index + l2.length <= l1.length ,否则会报错。
方法名作用
forEach遍历数组中的元素
map遍历数组中的所有元素,可以对元素进行处理,并返回新的 Iterable
elementAt获取指定索引位置处的元素
contains判断数组中是否含有指定元素
indexOf获取指定元素在数组中的索引
lastIndexOf从后向前查找指定元素在数组中的索引
indexWhere返回第一个满足条件的元素的索引
lastIndexWhere从后向前找,返回第一个满足条件的元素的索引
where根据指定条件,函数筛选每个元素,符合条件的元素组成一个新的 Iterable
firstWhere返回第一个满足条件的元素
indexWhere返回第一个满足条件的元素的索引
lastIndexWhere从后向前找,返回第一个满足条件的元素的索引
where根据指定条件,函数筛选每个元素,符合条件的元素组成一个新的 Iterable
firstWhere返回第一个满足条件的元素
every判断数组中是否每个元素都满足指定的条件
take从索引 0 位置处,取指定个数的元素
takeWhile从索引 0 位置处,查询满足指定条件的元素,直到出现第一个不符合条件的元素,然后返回前面符合条件的元素
skip跳过指定个数的元素,返回后面的元素
skipWhile根据指定条件,找到第一个不符合条件的元素,然后将该元素后面的所有元素返回
sublist从指定索引处截取数组
getRange截取指定索引范围内的元素
whereType从混合类型的数组中,筛选出指定类型的元素
// forEach 遍历数组中的元素

List<int> l1 = [8, 12, 4, 1];
l1.forEach((e) => print(e)); 
// 8 12 4 1
// map 遍历数组中的所有元素,可以对元素进行处理,并返回新的 Iterable

List<int> l1 = [8, 12, 4, 6, 22, 34, 10];
Iterable<bool> l2 = l1.map((e) => e > 10);
print(l2);
// (false, true, false, false, true, true, false)
Iterable<String> l3 = l1.map((e) => e > 10 ? "大" : "小");
print(l3);
// (小, 大, 小, 小, 大, 大, 小)
Iterable<num> l4 = l1.map((e) => e > 12 ? e / 2 : e * 2);
print(l4);
// (16, 24, 8, 12, 11.0, 17.0, 20)
// elementAt 获取指定索引位置处的元素 查看更多

List<String> l1 = ["周一", "周二", "周三", "周四"];
String str = l1.elementAt(2);
print(str); // 周三
// contains 判断数组中是否含有指定元素 查看更多

List<String> l1 = ["周一", "周二", "周三", "周四"];
bool a = l1.contains("周一");
bool b = l1.contains("周日");
print(a); // true
print(b); // false
// indexOf 获取指定元素在数组中的索引 查看更多

List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
int a = l1.indexOf("周三"); // 获取数组中第一次出现"周三"元素的索引
int b = l1.indexOf("周三", 3); // 从索引为3开始,查找第一次出现"周三"元素的索引
int c = l1.indexOf("周日");
print(a); // 2
print(b); // 4
print(c); // -1,数组中不存在指定元素,返回 -1
// lastIndexOf 从后向前查找指定元素在数组中的索引 查看更多

List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
int a = l1.lastIndexOf("周三");
int b = l1.lastIndexOf("周三", 3);
int c = l1.lastIndexOf("周日");
print(a); // 4
print(b); // 2
print(c); // -1
// indexWhere 返回第一个满足条件的元素的索引 查看更多

List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
int a = l1.indexWhere((e) => e == "周三");
print(a); // 2
// lastIndexWhere 从后向前找,返回第一个满足条件的元素的索引 查看更多

List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
int a = l1.lastIndexWhere((e) => e == "周三");
print(a); // 4
// where 根据指定条件,函数筛选每个元素,符合条件的元素组成一个新的 Iterable 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
Iterable<int> l2 = l1.where((e) => e > 10);
print(l2); // (12, 17, 33)

List<int> l3 = l1.where((e) => e >= 10).toList();
print(l3); // [12, 17, 33]
// firstWhere 返回第一个满足条件的元素 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
int a = l1.firstWhere((e) => e > 10);
print(a); // 12
// lastWhere 从后向前查找第一个满足条件的元素 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
int a = l1.lastWhere((e) => e > 10);
print(a); // 33
// singleWhere 获取满足指定条件的唯一元素 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
int a = l1.singleWhere((e) => e > 30);
int b = l1.singleWhere((e) => e > 33, orElse: () => -1);
int c = l1.singleWhere((e) => e > 10, orElse: () => null);
print(a); // 33
print(b); // -1。数组中没有满足条件的元素,返回 orElse 方法指定的返回值(-1是自己填的,你也可以设置为其它值)
print(c); // 报错。当数组中有多个满足条件的元素时,即使你设置了 orElse 的返回值,用 singleWhere 也会报错
// retainWhere 保留满足条件的元素(改变了原数组) 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
l1.retainWhere((e) => e > 10);
print(l1); // [12, 17, 33]
// any 判断数组中是否有满足指定条件的元素 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
bool a = l1.any((e) => e > 30);
print(a); // true
// every 判断数组中是否每个元素都满足指定的条件 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
bool a = l1.every((e) => e > 1);
print(a); // false
main() {
  List myList = [1, 3, 4, 5, 7, 8, 9];
  var newList = myList.where((value) {
    return value > 5;
  });
  print(newList.toList());

  List myList = [1, 3, 4, 5, 7, 8, 9];
  var f = myList.any((value) {
    //只要集合里面有满足条件的就返回true
    return value > 5;
  });
  print(f);

  List myList = [1, 3, 4, 5, 7, 8, 9];
  var f = myList.every((value) {
    //每一个都满足条件返回true  否则返回false
    return value > 5;
  });
  print(f);
}
// take 从索引 0 位置处,取指定个数的元素 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
Iterable<int> l2 = l1.take(3);
print(l2); // (8, 12, 4)
// takeWhile 从索引 0 位置处,查询满足指定条件的元素,直到出现第一个不符合条件的元素,然后返回前面符合条件的元素 查看更多

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
Iterable<int> l2 = l1.takeWhile((e) => e > 1);
print(l2); // (8, 12, 4)
// skip 跳过指定个数的元素,返回后面的元素

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
Iterable<int> l2 = l1.skip(4);
print(l2); // (17, 33, 10)
// skipWhile 根据指定条件,找到第一个不符合条件的元素,然后将该元素后面的所有元素返回

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
Iterable<int> l2 = l1.skipWhile((e) => e < 17);
print(l2); // (17, 33, 10)
// sublist 从指定索引处截取数组

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
List<int> l2 = l1.sublist(5);
print(l2); // [33, 10]

List<int> l3 = l1.sublist(2, 5);
print(l3); // [4, 1, 17] 含头不含尾
//getRange 截取指定索引范围内的元素

List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
Iterable<int> l2 = l1.getRange(2,5);
print(l2); // (4, 1, 17)
//whereType 从混合类型的数组中,筛选出指定类型的元素

List l1 = ["a", 15, "b", false, true, 20, "c",{"name":"AllenSu"}];
Iterable<String> l2 = l1.whereType();
Iterable<int> l3 = l1.whereType();
Iterable<bool> l4 = l1.whereType();
Iterable<Map> l5 = l1.whereType();
print(l2); // (a, b, c)
print(l3); // (15, 20)
print(l4); // (false, true)
print(l5); // ({name: AllenSu})

3.set类型

Set 表示对象的集合,每个对象只能出现一次。最主要的功能就是去除数组重复内容。

1)定义

 Set 集合名 = Set.from([元素一, 元素二, ...]);

2)属性

Set 中的常用属性有:

属性描述
first返回 Set 的第一个元素
last返回 Set 的最后一个元素
length返回 Set 的元素个数
isEmpty判断 Set 是否为空
isNotEmpty判断 Set 是否不为空
iterator返回迭代器对象,用于遍历集合
void main() {
  Set set = Set.from(['Jimmy', 'Ivy']);
  print(set.first); // Jimmy
  print(set.last); // Ivy
  print(set.length); // 2
  print(set.isEmpty); // false
  print(set.isNotEmpty); // true
  print(set.iterator); // Instance of '_CompactIterator<dynamic>'
}

3)方法

Set 中的常用方法有:

方法描述
add添加一个元素
addAll添加一些元素
toString转换字符串形式
join以指定的字符串连接,以字符串形式输出
contains集合中是否包含指定元素
containsAll集合中是否包含指定一些元素
elementAt(index)根据索引返回集合的元素
join以指定的字符串连接,以字符串形式输出
remove删除指定的元素
removeAll删除指定的一些元素
clear删除所有元素
void main() {
  Set set = Set.from([]);
  set.add('Jimmy');
  print(set.toString()); // {Jimmy}
  set.addAll(['Ivy', 'Kimmy']);
  print(set.join('-')); // Jimmy-Ivy-Kimmy
  print(set.contains('Timmy')); // false
  print(set.containsAll(['Jimmy', 'Kimmy'])); // true
  print(set.elementAt(1)); // Ivy
  set.remove('Kimmy');
  print(set); // {Jimmy, Ivy}
  set.removeAll(['Jimmy', 'Anonymous']);
  print(set); // {Ivy}
  set.clear();
  print(set); // {}
}

Set 遍历:

Set 集合遍历的方法有两种:

for...in 循环
调用 toList 方法返回一个 List 对象,再用 List 对象的遍历方法操作...
void main() {
  Set set = Set.from(['Jimmy', 'Ivy']);
  for(var item in set) {
    print(item);
    // Jimmy
    // Ivy
  }
  
  set.toList().forEach((item){
    print(item);
    // Jimmy
    // Ivy
  });
}

去重

void main(){
  List myList=['香蕉','苹果','西瓜','香蕉','苹果','香蕉','苹果'];
  var s=new Set();
  s.addAll(myList);
  print(s);
  // {香蕉, 苹果, 西瓜}
  print(s.toList());
  // [香蕉, 苹果, 西瓜]
}

4.Map类型

映射(Map)又称为关联数组,映射(Maps)是无序的键值对,相当于Java中的HashMap

1)定义

// 1.通过字面量创建Map,key必须加引号
var gifts = {
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
    };
    
// 2.使用Map类的构造函数创建对象
var pic = new Map();
// 往Map中添加键值对
pic['first'] = 'partridge';
pic['second'] = 'turtledoves';
pic['fifth'] = 'goden rings';
    
// 3.获取Map的长度
print(pic.Tength);
    
// 4.查找Map
pirnt(pic["first"]);
print(pic["four"]);  // 键不存在则返回 null
var persion={
  "name":"Dart",
  "age":"8"
};
print(persion);                //输出 {name: Dart, age: 8}
print(persion['name']);        //输出 Dart
print(persion['age']);         //输出 8

var persion1=new Map();
persion1["name"]="张三";
persion1["age"]="9";
print(persion1);                //输出 {name: 张三, age: 9}
print(persion1['name']);        //输出 张三
print(persion1['age']);         //输出 9

2)属性

通用属性:
forEach   
map
where
any
every
常用属性:
keys            获取所有的key值
values          获取所有的value值
isEmpty         是否为空
isNotEmpty      是否不为空
Map person = {"name": "张三", "age": 20, "sex": "男"};

print(person.keys.toList());
// [name, age, sex]
print(person.values.toList());
// [张三, 20, 男]
print(person.isEmpty);
// false
print(person.isNotEmpty);
// true

3)方法

remove(key)     删除指定key的数据
addAll({...})   合并映射  给映射内增加属性
containsValue   查看映射内的值  返回true/false
Map person = {"name": "张三", "age": 20, "sex": "男"};
person.addAll({
"work": ['敲代码', '送外卖'],
"height": 160
});
print(person);

person.remove("sex");
print(person);

5.总结

1)类型转换

  • Number 转换为 String 使用toString();
  • String转换为 Number 使用parse();
int.parse()
//将字符串转换为整型
String str='111';
var myNum=int.parse(str);    //输出 111
toString()
//将整型转换为字符串
var myNum = 18;
var str = myNum.toString();
print(str is String);        //输出 true
//注意转换时报异常
String str = '';   //字符串为空,转换为整型会报错
try {
  var myNum = int.parse(str);
  print("myNum");
} catch (err){
  print("转换错误");
}
tostringAsFixed(num)
// String 转 int
var one = int.parse('1' );
// string 转 double
var onePointone = double.parse('1.1');
// int 转 String
String oneAsStr = 1.toString() ;
// double 转 string
String piAsStr = 3.14159.tostringAsFixed(2); // 保留两位3.14

// Dart也支持整数位操作,<<、>>、&、|
print((3 << 1) == 6); // 0011 << 1 == 0110
print((3 >> 1) == 1); // 0011 >> 1 == 0001
print((3 4) == 7); // 0011  0100 == 0111

2)通用属性

forEach
// 以下结果等价
for(var item in myList){
	print(item);
}

myList.forEach((value){
	print("$value");
});
var s = new Set();
s.addAll([1, 222, 333]);
s.forEach((value) => print(value));
// 1
// 222
// 333
Map person = {"name": "张三", "age": 20};

person.forEach((key, value) {
print("$key---$value");
});
// name---张三
// age---20
map
// 以下结果等价
List myList = [1, 3, 4];
List newList = [];
for (var i = 0; i < myList.length; i++) {
	newList.add(myList[i] * 2);
}
print(newList);
// [2, 6, 8]

List myList=[1,3,4];      
var newList=myList.map((value){
  return value*2;
});
print(newList.toList());
// [2, 6, 8]
where
List myList = [1, 3, 4, 5, 7, 8, 9];
var newList = myList.where((value) {
return value > 5;
});
print(newList.toList());
// [7, 8, 9]

any,every
var f1 = myList.any((value) {
//只要集合里面有满足条件的就返回true
return value > 5;
});
print(f1);
// true

var f2 = myList.every((value) {
//每一个都满足条件返回true  否则返回false
return value > 5;
});
print(f2);
// false

三、运算符

  • 算数运算符
  • 关系运算符
  • 逻辑运算符
  • 赋值运算符
  • 条件表达式
  • 类型转换

1.算数运算符

Dart中又多出了一个整除运算符~/,与普通除号的区别是将相除后的结果取整返回。

int a=5;
int b=4;
 
print(a+b);  //加
print(a-b);  //减
print(a*b);  //乘
print(a/b);  //除
print(a%b);  //取余
print(a~/b); //取整
9
1
20
1.25
1
1

2.关系运算符

int a=5;
int b=4;
 
print(a==b);  //是否相等
print(a!=b);  //是否不相等
print(a>b);  //是否大于
print(a<b);  //是否小于
print(a>=b);  //是否大于或者等于
print(a<=b); //是否小于或者等于
false
true
true
false
true
false

3.逻辑运算符

1)!

var b =false;
print(!b);       //输出为true

2)&&

var a = true;
var b = false;
print(b && a);    // 输出false

3)||

var a = true;
var b = false;
print(b || a);    // 输出true

4.赋值运算符

1)=

int b = 6;

2)??=

int b;
b??=6;   //当 b在这之前没有被赋值,则在这行代码中会被赋值

3)复合赋值

int b = 6;
b += 10;
print(b);   //输出 16

5.类型判定运算符

以下是Dart增加的类型相关的运算符。

操作符解释
as用于类型转换
is如果对象是指定的类型就返回 True
is!如果对象不是指定的类型返回 True

当 obj 实现了 T 的接口时, obj is T 才是 true。类似于Java中的instanceof。

Dart中使用 as 操作符把对象转换为特定的类型,如无法转换则会抛出异常,因此在转换前最好使用is运算符进行检测。

// 将p转换为Person类型再操作
(p as Person) .name = 'Bruce':

1)as

Dart中使用 as 操作符把对象转换为特定的类型,如无法转换则会抛出异常,因此在转换前最好使用is运算符进行检测。

// 将p转换为Person类型再操作
(p as Person) .name = 'Bruce'

2)is

var str = '111';
if (str is String) {
    print("str is String type");
} else if (str is int) {
    print("str is int type");
} else {
    print("str is other type");
  }
}
// 结果 : 输出  str is String type

5.条件表达式

既三目运算符

解释:当等号=后的变量为true时,给变量赋值 : 前面的值,当flag为false时,给 变量赋值 : 后面的值
 
bool flag = true;
String b = flag ? "I am a boy " : " I am a girl";
print(b);
结果 : I am a boy
解释:flag 为true,赋值I am a boy

6.非空条件判断符

既??运算符

解释:当a为null时,赋值??符号后的10给a,然后将a赋值给b.
      当a不为null时,直接将a赋值给b
 
var a;
var b = a ?? 10;
print(b);    // 输出10
var a=20;
var b = a ?? 10;
print(b);    //输出20

7.级联运算符

见函数篇

8.空运算符

1)?

可将不为空的数据类型设置为空

main() {
  String? username = "张三"; // String?  表示username是一个可空类型
  username = null;
  print(username);

  int? a = 123; //  int? 表示a是一个可空类型
  a = null;
  print(a);

  List<String>? l1 = ["张三", "李四", "王五"];
  l1 = null;
  print(l1);
}

2)!

void printLength1(String? str) {
  if (str != null) {
    print(str.length);
  }else{
    print("str is null");
  }
}
void printLength2(String? str) {
  try {
    print(str!.length);
  } catch (e) {
    print("str is null");
  }
}
main(){
  printLength1("abc");
  // 3
  printLength2("abc");
  // 3
  printLength1(null);
  // str is null
  printLength2(null);
  // str is null
}

四、分支循环语句

1.分支语句

1)if else

条件判断语句

var b1=true;
if(b1){
print('true');
}else{
print('false');
}
true

2)switch case

var sex = "boy";
switch(sex){
  case "boy" :
    print("boy");
    break;
  case "girl":
    print("girl");
    break;
  default:
    print("传入的参数错误");
    break; 
}
boy

2.循环语句

1)for循环

for (int i = 0; i < 5; i++) {
  print(i);
}
0
1
2
3
4
for…in
var myList = ['Java','JavaScript','Dart'];
// for...in...循环,类似Java中的增强for
for (var it in myList ){
    print(it);
}
forEach
var myList = ['Java','JavaScript','Dart'];

// forEach循环。其参数为一个Function对象,这里传入一个匿名函数
myList.forEach((var it){
    print(it);
});

//可以使用匿名箭头函数简写
myList.forEach((it) => print(it));
main() {
  var myMap = {'zhangsan': '201901', 'lisi': '201902', 'wangwu': '201902'};
    
// forEach遍历Map
  myMap.forEach((k, v) => print("$k : $v"));
    
// 根据键获取值来遍历。通过keys返回Map中所有键的集合
  for (var k in myMap.keys) {
    print("$k : ${myMap[k]}");
  }
}

2)while循环

var i = 0;
while (i < 5) {
  print(i);
  i++;
}
0
1
2
3
4

do while: 先进行操作再判断条件

do {
  print(i);
  i++;
} while (i < 5);
0
1
2
3
4

3)break和continue

break :

  • 在switch语句中跳出switch结构
  • 在循环语句中跳出当前循环语句(注意只能向外跳出一层循环)

continue:

  • 只能在循环语句中使用
  • 跳出当前的此次循环,继续进行下一次循环

五、异常处理

针对不同异常进行不同处理,可以使用try...on处理异常,finally是可选的,用于最后的处理。

void main() {
  try {
// 使除数为0
    print(11 ~/ 0);
  } on UnsupportedError {
    print("除数为0");
  } on Exception {
    print("Exception");
  } finally {
    print("finally");
  }
}

不关心具体异常,只想捕获,避免异常继续传递,则可以使用try...catch处理

如果想获取更多异常信息,可以使用两个参数的catch,第二个参数是异常的调用栈信息

try {
	print(11~/0);}
catch(e,s){
    print(s);
}

;
break;
case “girl”:
print(“girl”);
break;
default:
print(“传入的参数错误”);
break;
}


~~~dart
boy

2.循环语句

1)for循环

for (int i = 0; i < 5; i++) {
  print(i);
}
0
1
2
3
4
for…in
var myList = ['Java','JavaScript','Dart'];
// for...in...循环,类似Java中的增强for
for (var it in myList ){
    print(it);
}
forEach
var myList = ['Java','JavaScript','Dart'];

// forEach循环。其参数为一个Function对象,这里传入一个匿名函数
myList.forEach((var it){
    print(it);
});

//可以使用匿名箭头函数简写
myList.forEach((it) => print(it));
main() {
  var myMap = {'zhangsan': '201901', 'lisi': '201902', 'wangwu': '201902'};
    
// forEach遍历Map
  myMap.forEach((k, v) => print("$k : $v"));
    
// 根据键获取值来遍历。通过keys返回Map中所有键的集合
  for (var k in myMap.keys) {
    print("$k : ${myMap[k]}");
  }
}

2)while循环

var i = 0;
while (i < 5) {
  print(i);
  i++;
}
0
1
2
3
4

do while: 先进行操作再判断条件

do {
  print(i);
  i++;
} while (i < 5);
0
1
2
3
4

3)break和continue

break :

  • 在switch语句中跳出switch结构
  • 在循环语句中跳出当前循环语句(注意只能向外跳出一层循环)

continue:

  • 只能在循环语句中使用
  • 跳出当前的此次循环,继续进行下一次循环

五、异常处理

针对不同异常进行不同处理,可以使用try...on处理异常,finally是可选的,用于最后的处理。

void main() {
  try {
// 使除数为0
    print(11 ~/ 0);
  } on UnsupportedError {
    print("除数为0");
  } on Exception {
    print("Exception");
  } finally {
    print("finally");
  }
}

不关心具体异常,只想捕获,避免异常继续传递,则可以使用try...catch处理

如果想获取更多异常信息,可以使用两个参数的catch,第二个参数是异常的调用栈信息

try {
	print(11~/0);}
catch(e,s){
    print(s);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木颤简叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值