Dart基础补充(一)

AS创建空的Dart工程

// 查看Dart SDK版本
$ dart --version
Dart SDK version: 2.13.4 (stable) (Wed Jun 23 13:08:41 2021 +0200) on "macos_x64"

// 查看Dart SDK安装的地方,发现是在flutter SDK包里边
$ which dart
/Users/wn/Documents/flutter/bin/dart
AS创建Dart空工程
  • Android Studio -> New Flutter Project

    选择Empty Project

  • 配置工程名

配置工程名
  • 新建Modules
    新建Modules
选择Dart类型
  • Module命名
    给Module命名

创建好的Dart空工程

Dart空工程

var 、final和const

新建flutter工程dart_demo1,工程类型为Application

  • 变量var的使用
void main() {
  // 声明一个变量a
  var a;
  print(a);
  a = 'hello world';
  print(a);
  a = 10;
  print(a + 10);

  // 变量也可以在声明的时候直接赋值
  var b = 666;
  print(b);
}

// 打印内容
null
hello world
20
666

使用var声明一个变量,可以赋值不同的类型;var声明的变量如果没有初始化,那么它的值为null;变量也可以在声明的时候直接赋值。

  • 最终变量final的使用
// 案例一
void main() {
  final c = 999;
  c = 'hello';
}
// 最终变量c不能被再次赋值
lib/main.dart:17:3: Error: Can't assign to the final variable 'c'.
  c = 'hello';
  ^
// 案例二 
final d;
print(d);
// 最终变量d在使用之前必须赋值,
// final声明的变量,如果没有赋值,是不能使用的
lib/main.dart:24:9: Error: Final variable 'd' must be assigned before it can be used.
  print(d);
        ^
// 案例三
final c;
c = 10;
print(c);

// 打印内容
10
  • 常量const的使用
// 常量声明的时候就必须赋值,常量也是不能修改的
const e = 10;
print(e);

// 打印内容
10

Dart的数据类型-num

num类型有两种intdouble

// 案例一
void numDemo() {
  num a;
  print(a);
}
// num类型在使用之前必须赋值
lib/main.dart:6:9: Error: Non-nullable variable 'a' must be assigned before it can be used.
  print(a);
        ^
// 案例二
void numDemo() {
  num a = 10;
  print(a);
  a = 1.5;
  print(a);
}

// 打印内容
10
1.5
// 案例三
int a = 10;
print(a);

a = 1.5;
print(a);
// int类型是不能被赋值为double类型的数值
lib/main.dart:7:7: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
  a = 1.5;
      ^
// 案例四
// double类型可以被赋值为int类型的数值
double a;
a = 10;
print(a);

// 打印内容
10
// 案例五
int a = 8;
print(a.isEven);//判断是否为偶数
print(a.isOdd);//判断是否为奇数

// 打印内容
true
false
// 案例六
// 算数运算符: + - * / %(取模) ~/(两数相除取整)
double a = 10;
int b = 8;
print(a ~/ b);
// 类型转换
print(a.toInt().isEven);
print(b.toDouble());

// 打印内容
1
true
8

Dart的数据类型-String

字符串使用单引号''双引号""创建

// 案例一
void stringDemo() {
  var a = 'a';
  var b = 'b';
  print(a + b);
}

// 打印内容
ab
// 案例二
var b = 'b';
b = 10;
// int类型不能被赋值到String类型中
lib/main.dart:6:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
  b = 10;
      ^
// 案例三
var a = 'a';
var b;
b = 'b';
b = 10;
print(a + b);
// String类型与int类型不能拼接
Error: Expected a value of type 'String', but got one of type 'int'
// 案例四
// 三个引号或双引号可以创建多行字符串
String str = 'abc';
print(str);
String str2 = "d"
              "e"
              "f";  //实际上是拼接在一起,为def
print(str2);

// 打印内容
abc
def


// 使用转义字符是字符串换行
String str2 = "d\n"
              "e\n"
              "f";
// 打印内容
d
e
f
// 案例五
// 三个引号不仅是换行,而且把回撤也保留了
String str2 = '''d
  e
  f''';
print(str2);

// 打印内容
d
  e
  f
// 案例六
// 可以像数组一样取字符串中的第几个字符
String str = 'abc';
print(str[0]);
print(str[1]);

// 打印内容
a
b
// 案例七
// 字符串也可以乘以数字,相当于对字符串复制几份
String str = 'abc';
print(str * 2);

// 打印内容
abcabc
// 案例八
// 使用{}来存放表达式
int a = 10;
int b = 20;
print('a + b = ${a + b}');

// 打印内容
a + b = 30

// 使用变量$c表示计算结果,没有表达式就不需要{}
int a = 10;
int b = 20;
int c = a + b;
print('a + b = $c');

// 打印内容
a + b = 30
// 案例九
// 使用r来打印转义字符
String str = 'abc\n123';
String str1 = r"abc\n123";
print(str);
print(str.length); 
print(str1);
print(str1.length); //打印字符串长度

// 打印内容
abc
123
7   // 转义字符是一个字符,相当于return
abc\n123  
8  

Dart的数据类型list&Map

  • list数组的使用,数组分为可变数组不可变数组
// 案例一
void listDemo() {
  // 数组中可以存放不同的数据类型
  // 创建可变数组list1
  var list1 = [1,2,3,'abc'];
  print(list1);
  // 获取数组中不同脚标对应的数据
  print(list1[3]);
  list1[3] = '123';
  print(list1);
}

// 打印内容
[1, 2, 3, abc]
abc
[1, 2, 3, 123]
// 案例二
// 创建不可变数组list1
var list1 = const [1,2,3,'abc'];
print(list1);
print(list1[3]);
list1[3] = '123';
print(list1);
// 不可变数组不能对元素进行赋值
Error: Unsupported operation: indexed set
// 案例三
// 可变数组的添加、插入、删除、清空操作
var list1 = [1,'abc'];
list1.add(2);
print(list1);
list1.insert(1, 3);
print(list1);
list1.remove(1);
print(list1);
list1.clear();
print(list1);

// 打印内容
[1, abc, 2]
[1, 3, abc, 2]
[3, abc, 2]
[]
// 案例四
// 可变数组的排序和截取
var list1 = [1,3,5,2,4,9,8,6];
list1.sort();
print(list1);
// 从脚标4开始到脚标7,注意不包含7,[4 7)
print(list1.sublist(4,7));

// 打印内容
[1, 2, 3, 4, 5, 6, 8, 9]
[5, 6, 8]
  • Map字典的使用,字典分为可变字典不可变字典
// 案例一
void mapDemo() {
  // 创建可变map
  var json1 = {'one': 1, 'two': 2};
  print(json1);
  print(json1['one']); //取值
  json1['one'] = 3; //赋值
  print(json1);
}

// 打印内容
{one: 1, two: 2}
1
{one: 3, two: 2}
// 案例二
// 创建不可变map
var json1 = const {'one': 1, 'two': 2};
json1['one'] = 3; //赋值
// 不可变map不能被赋值
Error: Unsupported operation: Cannot modify unmodifiable map
// 案例三
// 获取字典的keys 、values 、length
var json1 = {'one': 1, 'two': 2};
print(json1.length);
print(json1.keys);
print(json1.values);

// 打印内容
2
(one, two)
(1, 2)
// 案例四
// 数组转map
var list = ['a', 'b', 'c'];
print(list.asMap());

// 打印内容
{0: a, 1: b, 2: c}

Dart的运算符

  • 赋值运算符??=
void operatorDemo() {
  var a;
  a ??= 10; //如果a为null就赋值,如果有值就直接返回
  a ??= 5;
  a ??= 1;
  print(a);
}

// 打印内容
10

如果a为null就赋值,如果有值就直接返回。

  • 条件表达式??
var b;
print(b ?? 1);

// 打印内容
1

var b;
b = 5;
print(b ?? 1);

// 打印内容
5

如果b有值就返回b,否则就返回1

Dart中的方法&箭头函数

Dart中的方法也是一个对象,返回值和参数类型可以省略;当方法的执行语句只有一句的时候,可以使用箭头函数 => 表达式

  • 箭头函数
// 可以把方法的调用作为一个执行语句
void main() => functionDemo();
void functionDemo() => print('function'); 
  • 省略方法的返回值参数类型
void functionDemo() {
  print(sum(10, 20));
}

sum(a, b) {
  return a + b;
}

// 把sum方法简化成箭头函数
sum(a, b) => a + b;

// 把sum箭头函数修改为三目运算符类型
sum(a, b) => a == 1 ? a + b : a - b;

注意:不推荐省略方法的返回值参数类型

Dart方法的可选参数

可选参数:传递参数的时候必须带上形参的名字(否则不知道是哪个参数)

// 案例一
void functionDemo() {
  // 可选参数可以不按顺序传递
  print(sum1(1,c: 2,b: 3));
  // 只传两个参数
  print(sum1(1,b: 3));
}

sum1(int a, {b, c}) {
  b ??= 0;
  c ??= 0;
  return a + b + c;
}

// 打印内容
6
4
// 案例二
// 可选参数类型改为int
sum1(int a, {int b, int c}) {
  b ??= 0;
  c ??= 0;
  return a + b + c;
}

// 报错提示int类型不能为空
Try adding either an explicit non-'null' default value or the 'required' modifier.
sum1(int a, {int b, int c}) {
                        ^
lib/main.dart:9:3: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
  b ??= 0;
  ^
lib/main.dart:10:3: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
  c ??= 0;
  ^

// 解决方法一:nullability
// int? 告诉编译器,处理了后面为空的情况
sum1(int a, {int? b, int? c}) {
  b ??= 0;
  c ??= 0;
  return a + b + c;
}

// 解决方法二:可选参数给默认值
sum1(int a, {int b = 0, int c = 0}) {
  return a + b + c;
}
// 案例三
sum1(int a, {int b = a, int c = a}) {
  return a + b + c;
}

// 找不到参数a
Waiting for connection from debug service on Chrome...
lib/main.dart:8:22: Error: Getter not found: 'a'.
sum1(int a, {int b = a, int c = a}) {
                     ^
lib/main.dart:8:33: Error: Getter not found: 'a'.
sum1(int a, {int b = a, int c = a}) {
                                ^
// 案例四:传递的可选参数是有顺序的
void functionDemo() {
  print(sum2(1, 2, 3));
  // 参数b的值为3,不能跳过参数b给参数c传值
  print(sum2(1, 3));
}

sum2(int a, [int b = 0, int c = 0]) {
  return a + b + c;
}

// 打印内容
6
4

Dart方法作为参数传递

方法也是对象:使用场景作为参数传递

// 案例一
void functionDemo() {
  // Dart的方法也是一个对象
  var hello = printHello;
  hello();
}

printHello() => print('hello');

// 打印内容
hello
// 案例二
void functionDemo() {
  var list = [1, 2, 3, 4];
  list.forEach(print);
}

// 打印内容
1
2
3
4

// 查看forEach源码:遍历list数组,把数组内的元素当作方法f的参数
void forEach(void f(E element)) {
  for (E element in this) f(element);
}
// 案例三:使用自定义forEach方法和自定义print方法
void functionDemo() {
  var list = [1, 2, 3, 4];
  forEachDemo(list, printElement);
}

forEachDemo(List list, void func(var element)) {
  for (var e in list) func(e);
}

int b = 0;
printElement(var a) {
  b++;
  print('元素$b = $a');
}

// 打印内容
元素1 = 1
元素2 = 2
元素3 = 3
元素4 = 4

Dart中的匿名函数

匿名函数:没有方法名称的方法

// 案例一 
void functionDemo() {
  // 匿名函数赋值,保留其地址来调用
  var func = (){
    print('匿名函数');
  };
  func();
}

// 打印内容
匿名函数
// 案例二
void functionDemo() {
  // 立即执行的匿名函数
  ((){
    print('立即执行函数');
  })();
}

// 打印内容
立即执行函数
// 案例三
void functionDemo() {
  var list = [1, 2, 3, 4];
  int b = 0;
  // 函数式编程,类似于OC的block
  // 匿名函数作为参数的实战
  // 这里的匿名函数与闭包还是有区别的,闭包是定义在函数内部的函数
  forEachDemo(list, (var a) {
    b++;
    print('元素$b = $a');
  });
}

forEachDemo(List list, void func(var element)) {
  for (var e in list) func(e);
}

// 打印内容
元素1 = 1
元素2 = 2
元素3 = 3
元素4 = 4

Dart中的闭包

闭包的概念:定义在函数内部的函数,闭包也是一个对象;
闭包的作用:可以访问外部函数的局部变量;闭包就是一个闭环,让内部函数可以持续访问外部函数。

// 案例一
void closureDemo() {
  var func = funcA();
  func();
  func();
  func();
  func();
}

funcA() {
  int count = 0;
  return () => print(count++); //这个匿名函数就是一个闭包
}

// 打印内容
0
1
2
3

由打印内容说明count一直在内存中,并没有释放,这就是闭包的典型作用;funcA函数执行完毕,只要我们获取到funcA函数返回的闭包,那么funcA函数中的变量就会一直存在,不会释放。

// 案例二
void closureDemo() {
  var func = funcA();
  func();
  func();
  func();
  func();

  var func2 = funcA();
  func2();
  func2();
  func2();
  func2();
}

// 打印内容
0
1
2
3
0
1
2
3

func2获取的是一个新的闭包对象,所以count就是一个全新的栈内存。

你可能感兴趣的:(Dart基础补充(一))