Dart 语言基础

Dart 是什么

Dart 是由 Google 开发的一种客户端优化的编程语言,专为快速构建高质量应用而设计。它是 Flutter 的官方开发语言。

Dart is an approachable, portable, and productive programming language for building high-quality apps on any platform.

dart.dev

为什么选择 Dart

特性说明
类型安全支持空安全 (Null Safety),编译时捕获空指针错误
高性能AOT 编译为原生代码,JIT 支持热重载开发
跨平台编译到 ARM、x64、JavaScript、WebAssembly
现代语法async/await、Records、Patterns、模式匹配
Flutter 专属与 Flutter 深度集成,UI 即代码

知识结构

Hello World

Dart 程序的入口是 main 函数。

void main() {
print('Hello, Dart!');
}

变量和常量

变量声明

// 使用 var 自动推断类型
var name = 'Dart';
var age = 10;
// 显式声明类型
String language = 'Dart';
int version = 3;
double pi = 3.14159;
bool isAwesome = true;

var、final、const 对比

特性varfinalconst
可重新赋值可以不可以不可以
初始化时机运行时运行时编译时
类型推断支持支持支持
值的可变性值可变引用不可变,值可能可变深度不可变
// var: 可重新赋值的变量
var name = 'Dart';
name = 'Flutter'; // OK - 可以重新赋值
// final: 只能赋值一次,运行时确定
final now = DateTime.now(); // OK - 可以使用运行时值
// now = DateTime.now(); // Error - 不能重新赋值
// const: 编译时常量,值必须在编译时确定
const pi = 3.14159;
const maxItems = 100;
// const time = DateTime.now(); // Error - DateTime.now() 是运行时值

集合的可变性差异

// var 集合:引用和内容都可变
var list1 = [1, 2, 3];
list1.add(4); // OK - 可以修改内容
list1 = [5, 6, 7]; // OK - 可以重新赋值
// final 集合:引用不可变,但内容可变
final list2 = [1, 2, 3];
list2.add(4); // OK - 可以修改内容
// list2 = [5, 6, 7]; // Error - 不能重新赋值
// const 集合:引用和内容都不可变
const list3 = [1, 2, 3];
// list3.add(4); // Error - 不能修改内容
// list3 = [5, 6, 7]; // Error - 不能重新赋值
// final + const:引用不可变,内容也不可变
final list4 = const [1, 2, 3];
// list4.add(4); // Error - 不能修改内容
// list4 = [5, 6, 7]; // Error - 不能重新赋值

使用建议

// 1. 优先使用 const(性能最好,编译时优化)
const appName = 'MyApp';
const defaultPadding = 16.0;
// 2. 需要运行时确定的不可变值用 final
final currentUser = await fetchUser();
final screenWidth = MediaQuery.of(context).size.width;
// 3. 只有需要重新赋值时才用 var
var counter = 0;
counter++; // 需要修改
// 4. 类成员变量
class Config {
static const version = '1.0.0'; // 编译时常量
final String userId; // 实例创建时确定
var isLoggedIn = false; // 需要修改的状态
Config(this.userId);
}

可空类型

Dart 2.12 引入了空安全(Null Safety),变量默认不能为 null。

// 普通变量不能为 null
String name = 'Dart';
// name = null; // 编译错误
// 使用 ? 声明可空变量
String? nullableName;
nullableName = null; // 可以
// 空值检查
print(nullableName?.length); // 安全访问
print(nullableName ?? 'default'); // 空值合并
print(nullableName!.length); // 断言非空(谨慎使用)

内置类型

Number

// 整数
int count = 42;
int hex = 0xFF;
// 浮点数
double price = 9.99;
double exponent = 1.42e5;
// num 可以是 int 或 double
num value = 100;
value = 3.14;

Boolean

bool isReady = true;
bool isEmpty = false;
// 条件表达式
var result = isEmpty ? 'Empty' : 'Not empty';

String

// 字符串声明
String single = 'Single quotes';
String double = "Double quotes";
String multiLine = '''
This is a
multi-line string
''';
// 字符串插值
var name = 'Dart';
print('Hello, $name!');
print('Length: ${name.length}');
// 常用方法
'hello'.toUpperCase(); // HELLO
' trim '.trim(); // trim
'hello'.contains('ell'); // true
'hello'.replaceAll('l', 'L'); // heLLo
'a,b,c'.split(','); // [a, b, c]

List

// 声明列表
var list = [1, 2, 3];
List<String> names = ['Alice', 'Bob'];
// 常用操作
list.add(4);
list.addAll([5, 6]);
list.remove(1);
list.removeAt(0);
print(list.length);
print(list.first);
print(list.last);
print(list.isEmpty);
// 遍历
for (var item in list) {
print(item);
}
// 函数式操作
list.map((e) => e * 2);
list.where((e) => e > 2);
list.reduce((a, b) => a + b);

Set

// 集合(元素唯一)
var set = {1, 2, 3};
Set<String> tags = {'dart', 'flutter'};
set.add(4);
set.add(1); // 不会重复添加
set.contains(2); // true
set.remove(1);

Map

// 键值对
var map = {'name': 'Dart', 'version': 3};
Map<String, int> scores = {'math': 90, 'english': 85};
// 操作
map['type'] = 'language';
print(map['name']);
map.remove('version');
// 遍历
map.forEach((key, value) {
print('$key: $value');
});
for (var entry in map.entries) {
print('${entry.key}: ${entry.value}');
}

Dynamic 与 Object

// dynamic: 关闭类型检查
dynamic anything = 'Hello';
anything = 123;
anything = true;
// Object: 所有类的基类
Object obj = 'Hello';
obj = 123;
// obj.length; // 编译错误,Object 没有 length 属性

Enum

enum Status { pending, approved, rejected }
var status = Status.pending;
switch (status) {
case Status.pending:
print('Waiting...');
break;
case Status.approved:
print('Approved!');
break;
case Status.rejected:
print('Rejected.');
break;
}
// Dart 2.17+ 增强枚举
enum Color {
red(0xFF0000),
green(0x00FF00),
blue(0x0000FF);
final int value;
const Color(this.value);
}

Records (Dart 3.0+)

Records 是 Dart 3.0 引入的新类型,用于将多个值打包成一个不可变的聚合对象。这解决了函数只能返回单个值的限制。

Records are an anonymous, immutable, aggregate type.

dart.dev/language/records

// 创建记录 - 位置字段
var point = (10, 20);
print(point.$1); // 10 (通过 $1, $2... 访问位置字段)
print(point.$2); // 20
// 创建记录 - 命名字段
var person = (name: 'Alice', age: 25);
print(person.name); // Alice
print(person.age); // 25
// 混合使用位置和命名字段
var mixed = ('first', 2, third: true);
print(mixed.$1); // first
print(mixed.$2); // 2
print(mixed.third); // true

函数返回多个值

Records 最常见的用途是让函数返回多个值:

// 返回多个值 - 位置字段
(String, int) getUserInfo() {
return ('Alice', 25);
}
// 返回多个值 - 命名字段(更清晰)
({String name, int age}) getUserInfoNamed() {
return (name: 'Alice', age: 25);
}
void main() {
// 解构位置字段
var (name, age) = getUserInfo();
print('$name is $age years old');
// 解构命名字段
var (:name, :age) = getUserInfoNamed();
// 等同于 var (name: name, age: age) = getUserInfoNamed();
}

Records vs 类

特性RecordsClass
定义方式匿名,无需定义需要 class 定义
可变性不可变可变或不可变
相等性按值比较(结构相等)默认按引用比较
适用场景简单数据聚合、多返回值复杂逻辑、需要方法
// Records 相等性:相同结构和值即相等
var r1 = (name: 'Dart', version: 3);
var r2 = (name: 'Dart', version: 3);
print(r1 == r2); // true - 按值比较
// 类型别名简化复杂记录
typedef Point = ({int x, int y});
typedef UserInfo = ({String name, int age, String email});
Point origin = (x: 0, y: 0);

运算符

算术运算符

int a = 10;
int b = 3;
print(a + b); // 13
print(a - b); // 7
print(a * b); // 30
print(a / b); // 3.333...
print(a ~/ b); // 3 (整除)
print(a % b); // 1 (取余)
a++; // 11
b--; // 2

比较与逻辑运算符

// 比较运算符
print(5 == 5); // true
print(5 != 3); // true
print(5 > 3); // true
print(5 >= 5); // true
print(3 < 5); // true
print(3 <= 3); // true
// 逻辑运算符
print(true && false); // false
print(true || false); // true
print(!true); // false

赋值运算符

var x = 10;
x += 5; // x = x + 5
x -= 3; // x = x - 3
x *= 2; // x = x * 2
x ~/= 4; // x = x ~/ 4
// 空值赋值
String? name;
name ??= 'default'; // 仅当 name 为 null 时赋值

自定义类操作符

可以为自定义类重载操作符。

class Vector {
final double x, y;
Vector(this.x, this.y);
// 重载 + 运算符
Vector operator +(Vector other) {
return Vector(x + other.x, y + other.y);
}
// 重载 * 运算符
Vector operator *(double scalar) {
return Vector(x * scalar, y * scalar);
}
// 重载 == 运算符
@override
bool operator ==(Object other) {
if (other is! Vector) return false;
return x == other.x && y == other.y;
}
@override
int get hashCode => Object.hash(x, y);
@override
String toString() => 'Vector($x, $y)';
}
void main() {
var v1 = Vector(1, 2);
var v2 = Vector(3, 4);
print(v1 + v2); // Vector(4.0, 6.0)
print(v1 * 2); // Vector(2.0, 4.0)
}

函数

基本函数

// 普通函数
int add(int a, int b) {
return a + b;
}
// 箭头函数(单表达式)
int multiply(int a, int b) => a * b;
// 无返回值
void sayHello(String name) {
print('Hello, $name!');
}

可选参数

// 位置可选参数
void greet(String name, [String? title, String suffix = '!']) {
print('Hello, ${title ?? ''} $name$suffix');
}
greet('Alice');
greet('Bob', 'Mr.');
greet('Charlie', 'Dr.', '.');

命名参数

// 命名参数(默认可选)
void createUser({String? name, int age = 0, required String email}) {
print('Name: $name, Age: $age, Email: $email');
}
createUser(email: 'test@example.com');
createUser(name: 'Alice', age: 25, email: 'alice@example.com');

匿名函数与闭包

// 匿名函数
var list = [1, 2, 3];
list.forEach((item) {
print(item);
});
// 闭包
Function makeAdder(int addBy) {
return (int i) => i + addBy;
}
var add2 = makeAdder(2);
print(add2(3)); // 5

高阶函数

// 函数作为参数
void repeat(int times, void Function(int) action) {
for (var i = 0; i < times; i++) {
action(i);
}
}
repeat(3, (i) => print('第 $i 次'));
// 函数作为返回值
Function multiplyBy(int factor) {
return (int value) => value * factor;
}
var triple = multiplyBy(3);
print(triple(4)); // 12

级联操作符

使用 .. 可以对同一对象进行连续操作。

class Person {
String name = '';
int age = 0;
void introduce() {
print('I am $name, $age years old.');
}
}
void main() {
var person = Person()
..name = 'Alice'
..age = 25
..introduce();
// 等同于
// var person = Person();
// person.name = 'Alice';
// person.age = 25;
// person.introduce();
}

控制流

if-else

var score = 85;
if (score >= 90) {
print('优秀');
} else if (score >= 60) {
print('及格');
} else {
print('不及格');
}
// 三元运算符
var result = score >= 60 ? '及格' : '不及格';

switch

var command = 'start';
switch (command) {
case 'start':
print('Starting...');
break;
case 'stop':
print('Stopping...');
break;
case 'restart':
print('Restarting...');
break;
default:
print('Unknown command');
}
// Dart 3.0 switch 表达式
var message = switch (command) {
'start' => 'Starting...',
'stop' => 'Stopping...',
_ => 'Unknown'
};

模式匹配 (Dart 3.0+)

Dart 3.0 引入了强大的模式匹配 (Pattern Matching) 功能,可以在 switch、if-case、变量声明等场景中使用。

Patterns are a syntactic category that let you match and destructure values.

dart.dev/language/patterns

if-case 模式匹配

var data = {'name': 'Alice', 'age': 25};
// if-case 解构 Map
if (data case {'name': String name, 'age': int age}) {
print('$name is $age years old');
}
// 匹配列表
var list = [1, 2, 3];
if (list case [var first, var second, ...]) {
print('First: $first, Second: $second');
}
// 匹配对象
var point = Point(10, 20);
if (point case Point(x: var x, y: var y) when x > 0) {
print('Point in positive x: ($x, $y)');
}

switch 模式匹配

// 解构 Records
(int, String) getData() => (200, 'OK');
void handleResponse() {
var response = getData();
switch (response) {
case (200, var message):
print('Success: $message');
case (404, _):
print('Not found');
case (var code, var message) when code >= 500:
print('Server error $code: $message');
case (var code, _):
print('Other status: $code');
}
}
// 解构对象
class Point {
final int x, y;
Point(this.x, this.y);
}
String describePoint(Point p) => switch (p) {
Point(x: 0, y: 0) => 'Origin',
Point(x: 0, y: var y) => 'On Y axis at $y',
Point(x: var x, y: 0) => 'On X axis at $x',
Point(x: var x, y: var y) when x == y => 'On diagonal at $x',
Point(x: var x, y: var y) => 'Point at ($x, $y)',
};

常用模式类型

模式类型示例说明
常量模式case 42:匹配特定值
变量模式case var x:绑定值到变量
通配符case _:匹配任意值,不绑定
记录模式case (a, b):解构 Records
对象模式case Point(x: 0):解构对象属性
列表模式case [a, b, ...]:解构列表
Map 模式case {'key': value}:解构 Map
逻辑或case 1 | 2 | 3:匹配多个值
守卫条件case x when x > 0:添加额外条件

变量声明解构

// 解构列表
var [a, b, ...rest] = [1, 2, 3, 4, 5];
print('$a, $b, $rest'); // 1, 2, [3, 4, 5]
// 解构 Map
var {'name': name, 'age': age} = {'name': 'Bob', 'age': 30, 'city': 'NYC'};
// 解构 Record
var (lat, lng) = getCoordinates();
// 交换变量(无需临时变量)
var x = 1, y = 2;
(x, y) = (y, x);
print('$x, $y'); // 2, 1
// for 循环解构
var points = [(1, 2), (3, 4), (5, 6)];
for (var (x, y) in points) {
print('Point: ($x, $y)');
}

循环

for 循环

// 标准 for
for (var i = 0; i < 5; i++) {
print(i);
}
// for-in
var list = ['a', 'b', 'c'];
for (var item in list) {
print(item);
}
// forEach
list.forEach((item) => print(item));

while 与 do-while

// while
var count = 0;
while (count < 3) {
print(count);
count++;
}
// do-while
var i = 0;
do {
print(i);
i++;
} while (i < 3);

break 与 continue

for (var i = 0; i < 10; i++) {
if (i == 5) break; // 终止循环
if (i % 2 == 0) continue; // 跳过本次
print(i);
}

异常处理

void main() {
try {
var result = 10 ~/ 0;
print(result);
} on IntegerDivisionByZeroException {
print('不能除以零');
} on FormatException catch (e) {
print('格式错误: $e');
} catch (e, stackTrace) {
print('未知错误: $e');
print('堆栈: $stackTrace');
} finally {
print('清理资源');
}
}
// 抛出异常
void validateAge(int age) {
if (age < 0) {
throw ArgumentError('年龄不能为负数');
}
if (age > 150) {
throw RangeError('年龄超出范围');
}
}
// 自定义异常
class ValidationException implements Exception {
final String message;
ValidationException(this.message);
@override
String toString() => 'ValidationException: $message';
}

泛型

泛型类

class Box<T> {
T value;
Box(this.value);
T getValue() => value;
void setValue(T newValue) => value = newValue;
}
void main() {
var intBox = Box<int>(42);
var stringBox = Box<String>('Hello');
print(intBox.getValue()); // 42
print(stringBox.getValue()); // Hello
}

泛型函数

T first<T>(List<T> list) {
return list.first;
}
void main() {
print(first<int>([1, 2, 3])); // 1
print(first(['a', 'b', 'c'])); // a (类型推断)
}

泛型约束

// 限制 T 必须是 num 的子类
class NumberBox<T extends num> {
T value;
NumberBox(this.value);
T add(T other) => (value + other) as T;
}
var intBox = NumberBox<int>(10);
var doubleBox = NumberBox<double>(3.14);
// var stringBox = NumberBox<String>('x'); // 编译错误

Future 与异步

Future 基础

Future<String> fetchData() {
return Future.delayed(
Duration(seconds: 2),
() => 'Data loaded',
);
}
void main() {
print('Start');
fetchData().then((data) {
print(data);
}).catchError((error) {
print('Error: $error');
}).whenComplete(() {
print('Done');
});
print('Waiting...');
}
// 输出: Start -> Waiting... -> (2秒后) Data loaded -> Done

async/await

Future<String> fetchUser() async {
await Future.delayed(Duration(seconds: 1));
return 'Alice';
}
Future<String> fetchEmail(String user) async {
await Future.delayed(Duration(seconds: 1));
return '$user@example.com';
}
Future<void> main() async {
print('Start');
try {
var user = await fetchUser();
print('User: $user');
var email = await fetchEmail(user);
print('Email: $email');
} catch (e) {
print('Error: $e');
}
print('Done');
}

并行执行

Future<void> main() async {
// 并行执行多个 Future
var results = await Future.wait([
fetchUser(),
fetchData(),
]);
print(results); // [user, data]
}

Stream 异步流

Stream 用于处理一系列异步事件,而 Future 只能处理单个异步结果。

// 使用 async* 创建 Stream
Stream<int> countTo(int n) async* {
for (int i = 1; i <= n; i++) {
await Future.delayed(Duration(milliseconds: 500));
yield i; // 逐个发出值
}
}
// 使用 await for 消费 Stream
Future<void> main() async {
print('Start counting:');
await for (var number in countTo(5)) {
print(number);
}
print('Done!');
}
// 输出: Start counting: -> 1 -> 2 -> 3 -> 4 -> 5 -> Done!

Stream 操作

Stream<int> numbers = Stream.fromIterable([1, 2, 3, 4, 5]);
// 转换操作
numbers
.map((n) => n * 2) // [2, 4, 6, 8, 10]
.where((n) => n > 4) // [6, 8, 10]
.listen((n) => print(n)); // 监听每个值
// 聚合操作
var sum = await numbers.reduce((a, b) => a + b);
var list = await numbers.toList();
var first = await numbers.first;

Stream vs Future

特性FutureStream
返回值数量单个值多个值序列
完成时机一次性完成可持续发送
适用场景HTTP 请求、文件读取WebSocket、用户输入、定时器
创建方式async 函数async* 函数 + yield

yield* 委托

Stream<int> rangeStream(int start, int end) async* {
for (int i = start; i <= end; i++) {
yield i;
}
}
Stream<int> combinedStream() async* {
yield* rangeStream(1, 3); // 委托给另一个 Stream
yield 100;
yield* rangeStream(4, 6);
}
// 输出: 1, 2, 3, 100, 4, 5, 6

类与对象

基本类

class Person {
String name;
int age;
// 构造函数简写
Person(this.name, this.age);
// 命名构造函数
Person.guest() : name = 'Guest', age = 0;
// 工厂构造函数
factory Person.fromJson(Map<String, dynamic> json) {
return Person(json['name'], json['age']);
}
// 方法
void introduce() {
print('I am $name, $age years old.');
}
// Getter
bool get isAdult => age >= 18;
// Setter
set nickname(String value) {
name = value;
}
}

私有成员

class BankAccount {
// 下划线开头为私有(库级别)
double _balance = 0;
double get balance => _balance;
void deposit(double amount) {
if (amount > 0) {
_balance += amount;
}
}
void withdraw(double amount) {
if (amount > 0 && amount <= _balance) {
_balance -= amount;
}
}
}

抽象类

abstract class Shape {
// 抽象方法(没有实现)
double area();
double perimeter();
// 普通方法
void describe() {
print('Area: ${area()}, Perimeter: ${perimeter()}');
}
}
class Circle extends Shape {
final double radius;
Circle(this.radius);
@override
double area() => 3.14159 * radius * radius;
@override
double perimeter() => 2 * 3.14159 * radius;
}
class Rectangle extends Shape {
final double width, height;
Rectangle(this.width, this.height);
@override
double area() => width * height;
@override
double perimeter() => 2 * (width + height);
}

类修饰符 (Dart 3.0+)

Dart 3.0 引入了多个新的类修饰符,用于更精细地控制类的继承和实现方式。

Class modifiers control how a class or mixin can be used, both from within its own library, and from outside the library where it’s defined.

dart.dev/language/class-modifiers

修饰符对比

修饰符可实例化可继承可实现说明
(无)可以可以可以普通类
abstract不可以可以可以抽象类
base可以可以不可以强制继承实现
interface可以不可以可以强制接口实现
final可以不可以不可以禁止扩展
sealed不可以同库可以同库可以穷尽检查

sealed 密封类

sealed 是最常用的新修饰符,用于创建受限的类型层次结构,配合模式匹配实现穷尽性检查。

// 定义密封类(只能在同一文件中扩展)
sealed class Result<T> {}
class Success<T> extends Result<T> {
final T data;
Success(this.data);
}
class Failure<T> extends Result<T> {
final String message;
Failure(this.message);
}
class Loading<T> extends Result<T> {}
// 使用 switch 表达式(编译器确保处理所有情况)
String handleResult(Result<String> result) => switch (result) {
Success(data: var data) => 'Got: $data',
Failure(message: var msg) => 'Error: $msg',
Loading() => 'Loading...',
// 无需 default,编译器知道所有可能的子类型
};
void main() {
var result = Success('Hello');
print(handleResult(result)); // Got: Hello
}

sealed 类的特点

  1. 隐式抽象:sealed 类不能直接实例化
  2. 同库限制:子类必须定义在同一个库(文件)中
  3. 穷尽检查:switch 表达式可以省略 default 分支
  4. 类型安全:编译器确保处理所有可能的子类型

实际应用:状态管理

// 定义 UI 状态
sealed class UiState {}
class InitialState extends UiState {}
class LoadingState extends UiState {}
class SuccessState extends UiState {
final List<String> items;
SuccessState(this.items);
}
class ErrorState extends UiState {
final String error;
ErrorState(this.error);
}
// 根据状态渲染 UI
Widget buildUI(UiState state) => switch (state) {
InitialState() => Text('Welcome!'),
LoadingState() => CircularProgressIndicator(),
SuccessState(items: var items) => ListView(children: items.map(Text.new).toList()),
ErrorState(error: var e) => Text('Error: $e'),
};

base 和 final 修饰符

// base: 强制使用 extends,不能用 implements
base class Animal {
void breathe() => print('Breathing...');
}
class Dog extends Animal {} // OK
// class Cat implements Animal {} // Error: 不能实现 base 类
// final: 禁止继承和实现
final class Config {
final String apiUrl;
Config(this.apiUrl);
}
// class MyConfig extends Config {} // Error: 不能继承 final 类

接口

Dart 没有 interface 关键字,任何类都可以作为接口使用。Dart 3.0 引入了 interface 修饰符来明确表示接口意图。

// 定义接口(使用抽象类)
abstract class Printable {
void printContent();
}
abstract class Savable {
void save();
}
// 实现多个接口
class Document implements Printable, Savable {
String content;
Document(this.content);
@override
void printContent() {
print(content);
}
@override
void save() {
print('Saving document...');
}
}

继承

class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
String breed;
Dog(String name, this.breed) : super(name);
@override
void speak() {
print('$name barks');
}
void fetch() {
print('$name fetches the ball');
}
}
void main() {
var dog = Dog('Buddy', 'Golden Retriever');
dog.speak(); // Buddy barks
dog.fetch(); // Buddy fetches the ball
}

Mixin

Mixin 用于在多个类之间共享代码,不需要继承关系。

mixin Swimming {
void swim() {
print('Swimming...');
}
}
mixin Flying {
void fly() {
print('Flying...');
}
}
mixin Walking {
void walk() {
print('Walking...');
}
}
class Duck with Swimming, Flying, Walking {
String name;
Duck(this.name);
}
class Fish with Swimming {
String name;
Fish(this.name);
}
void main() {
var duck = Duck('Donald');
duck.swim();
duck.fly();
duck.walk();
var fish = Fish('Nemo');
fish.swim();
// fish.fly(); // 错误,Fish 没有 Flying mixin
}

库与导入

导入库

// 导入 Dart 核心库
import 'dart:math';
import 'dart:convert';
import 'dart:async';
// 导入第三方包
import 'package:http/http.dart';
// 导入本地文件
import 'models/user.dart';
import '../utils/helpers.dart';

别名与部分导入

// 使用别名
import 'package:lib1/lib1.dart' as lib1;
import 'package:lib2/lib2.dart' as lib2;
lib1.Element element1 = lib1.Element();
lib2.Element element2 = lib2.Element();
// 只导入部分
import 'package:lib/lib.dart' show foo, bar;
// 隐藏部分
import 'package:lib/lib.dart' hide baz;

延迟加载

import 'package:heavy_lib/heavy.dart' deferred as heavy;
Future<void> loadHeavyLib() async {
await heavy.loadLibrary();
heavy.doSomething();
}

扩展方法

extension StringExtension on String {
String capitalize() {
if (isEmpty) return this;
return '${this[0].toUpperCase()}${substring(1)}';
}
bool get isEmail {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(this);
}
}
void main() {
print('hello'.capitalize()); // Hello
print('test@example.com'.isEmail); // true
}

下一步

学习了 Dart 基础后,可以开始学习 Flutter:

Read Next

Flutter 基础 - 给 React 开发者的入门指南

Read Previous

Kotlin 语言基础