您的当前位置:首页正文

【Flutter】- 基础语法

2024-10-31 来源:个人技术集锦


知识回顾

前言


源码分析

1. 变量、常量

常量:


变量:

  1. 需求:存储不可被修改的数据
  2. 实现:常量关键字:const 和 final
  3. 区别:final是运行时常量,值在运行时赋值;const是编译期常量,值在编译时赋值;

2. 数据类型 num string bool List Map

num String bool
num类型的变量既可以存整数也可以存小数
int类型的值可以赋值给double类型的变量,但是double类型的值不能赋值给int类型的变量

void main() {
  // 1. num类型 (整数、小数)
  num n1 = 10;
  print(n1); // 10
  n1 = 10.1;
  print(n1); // 10.1

  // 2. int类型 (整数)
  int n2 = 20;
  print(n2); // 20
  // 测试:将小数赋值给int
  // 报错:A value of type 'double' can't be assigned to a variable of type 'int'.
  // n2 = 20.2;

  // 3. double类型 (小数)
  double n3 = 30.3;
  print(n3); // 30.3
  // 测试:将整数赋值给double
  n3 = 30;
  print(n3); // 30.0
}

List

需求:使用一个变量有序的存储多个值
实现:列表(数组)关键字:List
● 定义列表  List 变量名 = [元素1, 元素2, ..., 元素n];1.1 需求:按序存储数字 1 3 5 71.2 需求:按序存储字符串 '居家' '美食' '服饰'1.3 列表中可以存储任意类型的数据
void main() {
  // 1. 定义列表:List 变量名 = [元素1, 元素2, ..., 元素n];
  // 1.1 需求:按序存储数字 1 3 5 7
  List nums = [1, 3, 5, 7];
  print(nums);
  
  // 1.2 需求:按序存储字符串 '居家' '美食' '服饰'
  List categories = ['居家', '美食', '服饰'];
  print(categories);
  
  // 1.3 列表中可以存储任意类型的数据
  List ret = [
    18,
    18.8,
    '美食',
    true,
    ['', 10],
    {}
  ];
  print(ret);
}

3. 综合

void main() {
  // 准备购物车数据
  List carts = [
    {"count": 2, "price": 10.0, "selected": true},
    {"count": 1, "price": 30.0, "selected": false},
    {"count": 5, "price": 20.0, "selected": true}
  ];

  // 记录总金额
  double totalAmount = 0.0;
  // 遍历购物车数据
  carts.forEach((element) {
    // 读取商品的勾选状态
    bool selected = element['selected'];
    // 如果商品被勾选 ,读取该商品的单价和数量,并计算价格小计
    if (selected) {
      double amount = element['count'] * element['price'];
      // 累加价格小计,计算总价
      totalAmount += amount;
    }
  });

  print(totalAmount);
}

4. 函数

void main() {
  // 2. 调用无参数无返回值函数
  func();
    
  // 4.调用有参数有返回值函数 
  int ret = sum(10, 20);
  print(ret); // 30
}

// 1. 定义函数:无参数无返回值函数
void func() {
  print('这是一个无参数无返回值函数');
}

// 3. 定义函数:有参数有返回值函数
// 需求:定义函数,计算任意两个整数的和,并返回计算结果
int sum(int a, int b) {
  int ret = a + b;
  return ret;
}

void main() {
  // 1.2 定义一个变量接收函数
  // var f = funcDemo1;
  Function f = funcDemo1;
  f();

  // 2.2 函数作为参数
  funcDemo2(funcDemo3);
}

// 1.1 函数可以作为对象赋值给其他变量
void funcDemo1() {
  print('funcDemo1');
}

// 2.1 函数可以作为参数传递给其他函数
void funcDemo2(Function func) {
  // 调用外界传入的函数
  func();
}

// 定义作为参数的函数: 把funcDemo3传入到funcDemo2
void funcDemo3() {
  print('funcDemo3');
}

匿名函数

void main() {
  // 匿名函数
  // 1. 匿名函数赋值给变量,并调用
  Function f = () {
    print('这是一个匿名函数');
  };
  f();

  // 2. 可以作为参数传递给其他函数去调用(回调函数)
  funcDemo(() {
    print('这个匿名函数是个参数');
  });
}

// 定义一个接收函数作为参数的函数
void funcDemo(Function func) {
  func();
}

箭头函数

void main() {
  int ret1 = sum1(10, 20);
  print(ret1);

  int ret2 = sum2(30, 40);
  print(ret2);
}

// 思考:以下代码可以简写吗?
sum1(a, b) {
  return a + b; // 函数体只有一行代码
}

// 箭头函数简写函数体:简写只有一行代码的函数体
sum2(a, b) => a + b;

综合

void main() {
    // 准备购物车数据
  List carts = [
    {"count": 2, "price": 10.0, "selected": true},
    {"count": 1, "price": 30.0, "selected": false},
    {"count": 5, "price": 20.0, "selected": true}
  ];

  // 调用封装的函数
  bool isSelectedAll = getSelectedState(carts);
  if (isSelectedAll) {
    print('全选');
  } else {
    print('非全选');
  }
}

// 核心逻辑:只要有任何一个商品是未勾选的,那么就是非全选
bool getSelectedState(List carts) {
  // 购物车初始的状态:假设默认是全选
  bool isSelectedAll = true;

  carts.forEach((element) {
    bool selected = element['selected'];
    // 核心代码:只要有任何一个商品是非勾选的,则购物车就是非全选
    if (selected == false) {
      isSelectedAll = selected;
    }
  });
    // 返回是否全选结果
  return isSelectedAll;
}

5. 类


6. 异步

import 'dart:io';

void main() {
  print('开始执行主线程--同步');
  getNetData().then((res) {
    print(res);
  }).catchError((error) {
    print(error);
  });
  print('会被阻塞吗???');
}

Future<String> getNetData() {
  return Future(() {
    sleep(Duration(seconds: 5));
    // return '成功获取网络数据';
    throw Exception('异步线程中错误');
  });
}


7. 示例

// 用户先登录,登录成功之后拿到token,然后再保存token到本地

import 'dart:io';

void main() {
  print('启动');
  login().then((token) {
    setToken(token).then((res) {});
  }).catchError((e) {});
  print('结束');
}

// 登录
Future<String> login() {
  return Future(() {
    sleep(Duration(seconds: 2));
    print('登录成功');
    // 返回token
    return '111111';
  });
}

// 存储token
Future<bool> setToken(String token) {
  return Future(() {
    sleep(Duration(seconds: 2));
    print('token:$token,存储成功');
    return true;
  });
}

8. async await 改造

// 用户先登录,登录成功之后拿到token,然后再保存token到本地

import 'dart:io';

void main() {
  print('启动');
  // login().then((token) {
  //   setToken(token).then((res) {});
  // }).catchError((e) {});
  doLogin();
  print('结束');
}

doLogin() async {
  try {
    String token = await login();
    bool res = await setToken(token);
    if (res) {
      print('操作成功');
    } else {
      print('操作失败');
    }
  } catch (e) {
    print(e);
  }
}

// 登录
Future<String> login() {
  return Future(() {
    sleep(Duration(seconds: 2));
    print('登录成功');
    // 返回token
    return '111111';
  });
}

// 存储token
Future<bool> setToken(String token) {
  return Future(() {
    sleep(Duration(seconds: 2));
    print('token:$token,存储成功');
    return true;
  });
}

9. dynamic 关闭编译器类型检查

/*
 dynamic会关闭编译器的类型检查
 1. 所以dynamic声明的变量在修改时不会检查类型
 2. 代码在编译期不会报错,但是在运行时就会报错
 */
void main() {
  List test = ['aaa', 111, true];

  List<dynamic> test2 = ['aaa', 'bbb', 22];
  List<String> test3 = ['aaa', 'bbb'];
}

10. 泛型

/*
 泛型的作用:使用泛型可以减少重复的代码
 封装函数:接收字符串就返回字符串,接收数字就返回数字,接收bool就返回bool
 */
void main() {
  // 1. 普通封装
  // String demoString(String str) {
  //   return str;
  // }

  // int demoInt(int a) {
  //   return a;
  // }

  // bool demoBool(bool b) {
  //   return b;
  // }

  // 2. 基于泛型封装
  // T 返回类型  demo<T>:返回类型  T:参数类型
  T demo<T>(T parm) {
    return parm;
  }

  // 调用
  String ret1 = demo<String>('demo');
  print(ret1);
  int ret2 = demo<int>(17);
  print(ret2);
  bool ret3 = demo<bool>(true);
  print(ret3);
}

拓展知识

总结

Top