Flutter从入门到实战-01-Dart语言基础

Flutter 从入门到实战(一):Dart 语言基础

面向刚接触 Flutter 的同学。内容以"能快速上手、适合发布博客"为目标,重新组织了章节结构与表达方式。

一、为什么要学 Flutter

Flutter 是 Google 开源的一套跨平台 UI 开发工具包,目标是使用一套代码,构建接近原生体验的多端应用。

它的价值主要体现在 3 个方面:

  1. 开发效率高

    一套 Dart 代码可以同时面向 Android、iOS、Web、Windows,甚至更多平台。

  2. 性能与体验更均衡

    Flutter 直接控制渲染层,在很多场景下能获得比较流畅的界面表现。

  3. 企业落地广

    课程讲义中提到,Flutter 在跨平台方案中拥有很高的采用率,已经有大量实际应用落地。

如果你想做跨端应用,但又不想分别深入 Android 和 iOS 原生开发,Flutter 是一个很值得投入的方向。

二、这套课程在讲什么

这份讲义整体是一个渐进式学习路径,核心分为 3 个部分:

  1. Dart 语言基础
  2. Flutter 组件核心
  3. 综合案例实战

其中第一份讲义的重点,主要是帮助我们先把 Dart 打牢。原因很简单:Flutter 的开发语言就是 Dart,如果语言基础不稳,后面的组件、状态、网络请求、项目结构都会学得很吃力。

三、开始前需要准备什么

1. 安装 Dart SDK

Dart SDK 是 Dart 官方提供的工具包,负责代码编写、运行、调试和编译。

我们可以把它理解为:想学 Flutter,先把 Dart 的运行环境准备好。

2. 准备编辑器

讲义中推荐了支持 AI 能力的编辑器 Trae,并提到两种常见工作方式:

  1. Tab 补全模式

    编写代码时,AI 根据上下文自动补全。

  2. Builder 协作模式

    直接用自然语言描述需求,让 AI 协助生成或修改代码。

不管你最终使用哪款编辑器,建议至少具备以下能力:

  1. Dart 语法高亮
  2. 自动补全
  3. 报错提示
  4. 运行与调试支持

3. Dart 初学者注意事项

刚开始写 Dart 时,先记住这几个基本规则:

  1. 文件后缀是 .dart
  2. 程序入口通常是 main()
  3. 大多数语句需要以分号结尾
  4. 大括号后的语法规则要和其他现代语言区分清楚

一个最简单的 Dart 程序如下:

dart 复制代码
void main() {
  print('Hello Dart');
}

四、变量与常量:先搞清楚"值会不会变"

在 Dart 中,最先要理解的是变量和常量的区别。

1. var:用于声明变量

当一个值后续还会变化时,使用 var

dart 复制代码
void main() {
  var age = 20;
  age = 21;
  print(age);
}

特点:

  1. Dart 会根据初始值自动推断类型
  2. 类型一旦推断完成,就不能随意改成别的类型
dart 复制代码
void main() {
  var name = 'Tom';
  // name = 18; // 会报错,因为 name 已经被推断为 String
}

2. const:编译时常量

如果一个值从定义开始就不会变化,并且在编译阶段就能确定,使用 const

dart 复制代码
void main() {
  const pi = 3.1415926;
  print(pi);
}

适用场景:

  1. 固定配置
  2. 数学常量
  3. 永远不会变化的字面量

3. final:运行时常量

如果一个值只会赋值一次,但这个值要等到运行时才能确定,就使用 final

dart 复制代码
void main() {
  final now = DateTime.now();
  print(now);
}

4. varconstfinal 怎么选

可以直接记住这套判断逻辑:

  1. 值会变:用 var
  2. 值不变,且编译时确定:用 const
  3. 值不变,但运行时才确定:用 final

五、Dart 常用数据类型

讲义重点介绍了 6 类常用数据类型:

  1. String
  2. int
  3. double
  4. num
  5. bool
  6. List
  7. Map
  8. dynamic

1. 字符串 String

字符串用于描述文本内容。

dart 复制代码
void main() {
  String title = 'Flutter 入门';
  print(title);
}
模板字符串

模板字符串是 Dart 中非常常用的能力:

dart 复制代码
void main() {
  String mealTime = '早上 8 点';
  String text = '我要在 $mealTime 的时候吃早饭';
  print(text);
}

如果是表达式,可以写成 ${表达式}

dart 复制代码
void main() {
  int a = 10;
  int b = 20;
  print('总和是 ${a + b}');
}

2. 数字类型 intdoublenum

它们的区别可以简单理解为:

  1. int:整数
  2. double:浮点数
  3. num:既可以表示整数,也可以表示小数
dart 复制代码
void main() {
  int age = 18;
  double score = 98.5;
  num price = 100;
  price = 99.9;
}

需要注意的是,不同数字类型之间并不是所有情况都能直接互相赋值,这一点在实际编码中要格外小心。

3. 布尔类型 bool

布尔类型只有两个值:truefalse

dart 复制代码
void main() {
  bool finishedHomework = true;
  print(finishedHomework);
}

4. 列表类型 List

当一个变量要保存多个值时,通常使用 List

dart 复制代码
void main() {
  List<String> students = ['小明', '小红', '小刚'];
  print(students);
}

常用操作包括:

  1. add():尾部添加元素
  2. addAll():追加一组元素
  3. remove():删除指定元素
  4. removeLast():删除最后一个元素
  5. forEach():遍历
  6. where():筛选
  7. every():判断是否全部满足条件

示例:

dart 复制代码
void main() {
  List<int> scores = [88, 92, 75, 99];
  scores.add(100);

  var goodScores = scores.where((item) => item >= 90);
  print(goodScores.toList());
}

5. 字典类型 Map

Map 用于保存键值对数据。

dart 复制代码
void main() {
  Map<String, String> dict = {
    'apple': '苹果',
    'banana': '香蕉',
  };

  print(dict['apple']);
}

常见操作有:

  1. forEach()
  2. addAll()
  3. containsKey()
  4. remove()
  5. clear()

6. 动态类型 dynamic

dynamic 表示动态类型,变量在运行时可以自由改变类型。

dart 复制代码
void main() {
  dynamic value = 'hello';
  value = 123;
  value = true;
  print(value);
}

但要注意,dynamic 会绕过很多编译期检查。也就是说,它虽然灵活,但会降低代码的安全性和可维护性。

dynamicvar 的区别

这是初学者特别容易混淆的一点:

  1. var 是类型推断,不是动态类型
  2. dynamic 才是真正意义上的"运行时再决定类型"

简化理解:

dart 复制代码
void main() {
  var a = 'hello';
  // a = 123; // 不允许

  dynamic b = 'hello';
  b = 123; // 允许
}

实际开发里,能不用 dynamic 就尽量不用。

六、空安全:Dart 非常重要的一道保护

空安全是 Dart 很重要的特性,它的核心目标是把很多空指针问题提前到编译阶段暴露出来,而不是等程序跑起来再崩。

1. 可空与不可空

默认情况下,类型是不可为空的:

dart 复制代码
String name = 'Flutter';

如果允许为空,要加 ?

dart 复制代码
String? name;

2. 常见空安全操作

常用写法包括:

  1. ?:声明可空类型
  2. ?.:空值安全调用
  3. !:非空断言
  4. ??:空值兜底
  5. ??=:当变量为空时再赋值

示例:

dart 复制代码
void main() {
  String? nickname;

  print(nickname?.length);
  print(nickname ?? '默认昵称');

  nickname ??= '游客';
  print(nickname);
}

! 虽然可以强制告诉编译器"这里一定不为空",但使用时一定要谨慎,否则还是可能在运行时报错。

七、运算符:写逻辑的基础

讲义中把常见运算符分成 4 类:

  1. 算术运算符
  2. 赋值运算符
  3. 比较运算符
  4. 逻辑运算符

1. 算术运算符

常见有:

  1. +
  2. -
  3. *
  4. /
  5. ~/:整除
  6. %:取余
dart 复制代码
void main() {
  print(7 / 2);   // 3.5
  print(7 ~/ 2);  // 3
  print(7 % 2);   // 1
}

2. 赋值运算符

常见有:

  1. =
  2. +=
  3. -=
  4. *=
  5. /=
  6. %=

3. 比较运算符

比较运算结果一定是布尔值:

  1. ==
  2. !=
  3. >
  4. <
  5. >=
  6. <=

4. 逻辑运算符

用于处理布尔表达式:

  1. &&:并且
  2. ||:或者
  3. !:取反
dart 复制代码
void main() {
  bool isAdult = true;
  bool hasTicket = false;

  print(isAdult && hasTicket);
}

八、流程控制:让程序能"判断"和"循环"

1. if 分支

if 用于条件判断,是最基础的控制结构。

dart 复制代码
void main() {
  int score = 85;

  if (score >= 90) {
    print('优秀');
  } else if (score >= 60) {
    print('及格');
  } else {
    print('不及格');
  }
}

2. 三元运算符

适合简化双分支逻辑:

dart 复制代码
void main() {
  int age = 20;
  String result = age >= 18 ? '成年人' : '未成年';
  print(result);
}

3. switch / case

当条件很多,而且本质上是在做"相等判断"时,switch 会更清晰。

dart 复制代码
void main() {
  String level = 'vip';

  switch (level) {
    case 'vip':
      print('高级会员');
      break;
    case 'normal':
      print('普通会员');
      break;
    default:
      print('游客');
  }
}

4. while 循环

while 适合"只要条件满足就一直执行"的场景。

dart 复制代码
void main() {
  int i = 0;

  while (i < 3) {
    print(i);
    i++;
  }
}

5. for 循环

for 是最常见的循环结构之一,也很适合遍历集合。

dart 复制代码
void main() {
  List<String> names = ['A', 'B', 'C'];

  for (int i = 0; i < names.length; i++) {
    print(names[i]);
  }
}

九、函数:把重复逻辑封装起来

函数是 Dart 代码组织和复用的核心能力。

1. 基本定义

dart 复制代码
int add(int a, int b) {
  return a + b;
}

2. 返回值

函数可以有返回值,也可以没有返回值:

dart 复制代码
int sum(int a, int b) {
  return a + b;
}

void logMessage() {
  print('hello');
}

3. 必传参数

dart 复制代码
String getUserName(String name) {
  return name;
}

4. 可选位置参数

使用中括号包裹:

dart 复制代码
String joinName(String first, [String? second]) {
  return '$first ${second ?? ''}';
}

适合参数顺序明确、可省略的场景。

5. 可选命名参数

使用大括号包裹,并通过"参数名: 值"的方式传参:

dart 复制代码
String createUser(String name, {int? age, String? city}) {
  return '$name - ${age ?? 0} - ${city ?? '未知'}';
}

void main() {
  print(createUser('Tom', age: 20, city: 'Shanghai'));
}

这种写法在 Flutter 中非常常见,因为可读性更好。

6. 匿名函数

匿名函数没有名字,常用于回调场景。

dart 复制代码
void main() {
  List<int> list = [1, 2, 3];

  list.forEach((item) {
    print(item);
  });
}

7. 箭头函数

当函数体只有一行时,可以用箭头函数简化:

dart 复制代码
int square(int x) => x * x;

十、类与面向对象:Flutter 开发绕不开的基础

Flutter 中大量代码都建立在类和对象之上,所以 Dart 的面向对象能力必须理解。

1. 定义类

dart 复制代码
class Person {
  String name;
  int age;

  Person(this.name, this.age);

  void study() {
    print('$name 正在学习');
  }
}

2. 构造函数

讲义中提到 3 类常见构造方式:

  1. 默认构造函数
  2. 命名构造函数
  3. 构造函数语法糖
默认构造函数
dart 复制代码
class Person {
  String name;
  int age;

  Person(this.name, this.age);
}
命名构造函数
dart 复制代码
class Person {
  String name;
  int age;

  Person(this.name, this.age);

  Person.guest()
      : name = '游客',
        age = 0;
}

3. 公有与私有成员

Dart 中以下划线开头的属性或方法,通常表示私有成员。

dart 复制代码
class User {
  String name = 'Tom';
  String _token = 'abc123';
}

4. 继承

Dart 是单继承语言,一个类只能有一个直接父类。

dart 复制代码
class Animal {
  void run() {
    print('动物在跑');
  }
}

class Dog extends Animal {
  @override
  void run() {
    print('小狗在跑');
  }
}

5. 多态

多态的核心是:同样的调用,面对不同对象时,会有不同实现。

这通常通过继承和方法重写来体现。

6. 抽象类与接口实现

当你只想约束规范,而不直接提供完整实现时,可以使用抽象类:

dart 复制代码
abstract class Pay {
  void pay();
}

class WechatPay implements Pay {
  @override
  void pay() {
    print('微信支付');
  }
}

7. 混入 mixin

如果你想在不走传统继承链的情况下,为类扩展能力,可以使用 mixin

dart 复制代码
mixin Runner {
  void run() {
    print('running');
  }
}

class Person with Runner {}

8. 泛型

泛型的价值是:既限制类型,又保留复用能力。

dart 复制代码
class Box<T> {
  T value;
  Box(this.value);
}

void main() {
  Box<String> box = Box<String>('hello');
  print(box.value);
}

十一、异步编程:Dart 处理耗时任务的方式

异步编程是 Flutter 开发里的高频内容,因为网络请求、文件读写、数据库访问都离不开它。

1. 事件循环

讲义中强调了一个关键点:Dart 是单线程模型,但它通过事件循环机制来协调同步任务和异步任务。

可以简单理解为:

  1. 先执行主线程中的同步代码
  2. 遇到耗时任务时,不阻塞主流程
  3. 等异步结果准备好后,再回到事件循环中处理

2. Future

Future 表示一个未来才会拿到结果的异步操作。

dart 复制代码
Future<String> getData() async {
  return '请求成功';
}

它通常有几种状态:

  1. 等待中
  2. 成功完成
  3. 失败完成

3. 链式调用

可以使用 then()catchError() 处理结果:

dart 复制代码
Future<String> getData() async {
  return 'ok';
}

void main() {
  getData()
      .then((value) {
        print(value);
      })
      .catchError((e) {
        print(e);
      });
}

4. async / await

相比链式调用,async / await 更接近同步代码的书写方式,可读性通常更好。

dart 复制代码
Future<String> getData() async {
  return 'ok';
}

void main() async {
  try {
    String result = await getData();
    print(result);
  } catch (e) {
    print(e);
  }
}

对于 Flutter 初学者来说,建议优先把 Futureasync / await 熟练掌握,因为后续请求接口、初始化数据、处理用户动作时都会频繁用到。

十二、学完这一讲,应该掌握什么

如果这份 Dart 基础讲义已经吸收得比较扎实,你至少应该具备下面这些能力:

  1. 能看懂并编写简单的 Dart 程序
  2. 能区分 varconstfinal
  3. 能熟练使用 StringListMap 等常见类型
  4. 理解空安全的基本规则与常见操作符
  5. 能使用分支、循环、函数组织基础逻辑
  6. 能理解类、构造函数、继承、多态、泛型等面向对象概念
  7. 能读懂并书写基本异步代码

十三、从 Dart 过渡到 Flutter,下一步学什么

Dart 基础打好之后,接下来进入 Flutter 会顺畅很多。下一阶段建议重点关注这些内容:

  1. Flutter 环境配置
  2. 工程目录结构
  3. main.dart 入口文件
  4. StatelessWidget 与 StatefulWidget
  5. 常见基础组件
  6. 页面布局与滚动容器
  7. 生命周期与状态更新

也就是说,Dart 解决的是"语言怎么写"的问题,而 Flutter 解决的是"界面怎么搭、交互怎么跑、项目怎么组织"的问题。

结语

很多人一学 Flutter 就急着写页面、搭项目、调接口,结果一遇到状态更新、空安全报错、回调函数、异步逻辑就开始混乱。根本原因往往不是 Flutter 太难,而是 Dart 基础不够稳。

真正高效的学习顺序应该是:

  1. 先把 Dart 语言基础打牢
  2. 再进入 Flutter 组件与项目开发
  3. 最后通过综合案例把知识串起来

如果你准备系统学习 Flutter,这一讲最值得反复练习的内容有 3 块:

  1. 变量与数据类型
  2. 函数与类
  3. 空安全与异步编程

把这 3 块吃透,后面学习 Flutter 会轻松很多。

相关推荐
xuankuxiaoyao1 小时前
Vue.js 插槽、作用域插槽、商品、阶段案例
android·vue.js·flutter
恋猫de小郭1 小时前
终于,Flutter 修复 Android 中文字体异常,但是很草台,不知怎么吐槽
android·前端·flutter
xmdy58662 小时前
Flutter + 开源鸿蒙跨端实战|基于空间地理信息的城市全域智慧泊车调度与多维运维管理平台 Day3
flutter·华为·开源
UnicornDev2 小时前
【Flutter x HarmonyOS 6】魔方计时APP——挑战页面的UI设计
flutter·ui·华为·harmonyos·鸿蒙
张风捷特烈3 小时前
状态管理大乱斗#08 | MobX 源码评析 - 透明魔法
android·前端·flutter
西西学代码5 小时前
Flutter---RichText(混合文本样式)
flutter
西西学代码5 小时前
Flutter---PageView
flutter
wuxianda103019 小时前
uniapp项目上架苹果商店4.3a被拒,3天极速解决方案2026.5.8
前端·人工智能·flutter·uni-app·ios上架·苹果上架·苹果4.3a
段子子1 天前
【在flutter项目中使用get_cli初始化项目】
flutter