Dart 语法完全指南:从入门到精通(附详细代码示例)

Dart语法全面解析与实践

Dart 语法完全指南:从入门到精通(附详细代码示例)

一、环境配置

Dart环境安装

安装方式:

  1. 访问 dart.dev 下载SDK
  2. 使用包管理器:
    • Windows: choco install dart-sdk
    • macOS: brew install dart
    • Linux: sudo apt-get install dart

验证安装:

dart --version

二、基础语法

2.1 变量与常量

Dart变量声明
// 显式声明类型
String name = 'Dart';
int age = 10;

// 类型推断(使用 var)
var city = 'Beijing';  // 自动推断为 String
var count = 100;       // 自动推断为 int

// 延迟初始化
String? email;  // 可空类型
late String description;  // 延迟初始化
const 常量
  • 编译时常量:值在编译期就确定
  • 深层不可变:对象及其内容都不可变
const PI = 3.14159;
const List<int> nums = [1, 2, 3];  // 不可修改的列表
// nums.add(4);  // 错误!不能修改
final 常量
  • 运行时常量:值在运行时确定,但只能赋值一次
  • 浅层不可变:引用不可变,但对象内容可能可变
final currentTime = DateTime.now();  // 运行时才知道值
final List<int> numbers = [1, 2, 3];
numbers.add(4);  // 可以!列表内容可修改
// numbers = [5, 6];  // 错误!不能重新赋值
dynamic 类型
  • 动态类型,可以赋任何值,关闭类型检查
dynamic value = 'Hello';
value = 123;      // 可以
value = true;     // 可以
print(value.anyMethod());  // 编译通过,但运行时可能报错
空安全机制
// 非空类型(默认)
String name = 'Dart';
// name = null;  // 错误!

// 可空类型(使用 ?)
String? nickname;
nickname = null;  // 正确

// 空值断言(!)
String? value = 'Hello';
print(value!.length);  // 确信不为null时使用

// 空值合并运算符(??)
String? name;
String displayName = name ?? 'Guest';  // name为null时使用'Guest'

// 条件访问(?.)
String? text;
print(text?.length);  // text为null时返回null,不报错

2.2 数据类型

String(字符串)
// 单引号或双引号
String str1 = 'Hello';
String str2 = "World";

// 字符串拼接
String fullName = 'John' + ' ' + 'Doe';
String message = 'Hello' ' ' 'World';  // 相邻字符串自动拼接

// 字符串插值
String name = 'Dart';
int version = 3;
print('$name $version');           // Dart 3
print('${name.toUpperCase()}');    // DART

// 多行字符串
String multiLine = '''
  这是第一行
  这是第二行
  这是第三行
''';

// 原始字符串(r前缀)
String path = r'C:\Users\name';  // 不转义反斜杠
数字类型
// int - 整数
int count = 10;
int hex = 0xDEADBEEF;

// double - 浮点数
double price = 19.99;
double exponent = 1.42e5;  // 科学计数法

// num - int 和 double 的父类
num value1 = 10;
num value2 = 10.5;

// 常用方法
int a = 5;
double b = 3.14159;
print(a.isEven);          // false
print(b.toStringAsFixed(2));  // 3.14
print(int.parse('42'));   // 字符串转int
print(double.parse('3.14'));  // 字符串转double
布尔类型
bool isActive = true;
bool isCompleted = false;

// 布尔运算
bool result = !isActive;  // 取反
bool and = isActive && isCompleted;
bool or = isActive || isCompleted;
列表类型(List)
// 创建列表
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];

// 访问元素
print(numbers[0]);      // 1
print(numbers.length);  // 5

// 添加元素
numbers.add(6);
numbers.addAll([7, 8, 9]);

// 删除元素
numbers.remove(3);      // 删除值为3的元素
numbers.removeAt(0);    // 删除索引0的元素

// 常用方法
print(numbers.first);   // 第一个元素
print(numbers.last);    // 最后一个元素
print(numbers.isEmpty); // 是否为空
numbers.forEach((num) => print(num));  // 遍历

// 不可变列表
const fixedList = [1, 2, 3];

// 扩展运算符
var list1 = [1, 2, 3];
var list2 = [0, ...list1];  // [0, 1, 2, 3]
Map(映射)
// 创建 Map
Map<String, int> ages = {
  'Alice': 25,
  'Bob': 30,
  'Charlie': 35
};

// 访问元素
print(ages['Alice']);  // 25

// 添加/修改元素
ages['David'] = 28;
ages['Alice'] = 26;

// 删除元素
ages.remove('Bob');

// 常用方法
print(ages.keys);       // 所有键
print(ages.values);     // 所有值
print(ages.length);     // 元素个数
print(ages.isEmpty);    // 是否为空
print(ages.containsKey('Alice'));  // 是否包含键

// 遍历
ages.forEach((key, value) {
  print('$key: $value');
});

2.3 运算符

算术运算符和赋值运算符
// 算术运算符
int a = 10, b = 3;
print(a + b);   // 13 加法
print(a - b);   // 7  减法
print(a * b);   // 30 乘法
print(a / b);   // 3.333... 除法(返回double)
print(a ~/ b);  // 3  整除
print(a % b);   // 1  取模

// 赋值运算符
int x = 5;
x += 3;   // x = x + 3  (8)
x -= 2;   // x = x - 2  (6)
x *= 2;   // x = x * 2  (12)
x ~/= 3;  // x = x ~/ 3 (4)

// 自增自减
int count = 0;
count++;  // 后置自增
++count;  // 前置自增
count--;  // 后置自减
--count;  // 前置自减

// 空值赋值(??=)
String? name;
name ??= 'Guest';  // name为null时才赋值
比较运算符和逻辑运算符
// 比较运算符
int a = 5, b = 10;
print(a == b);   // false 等于
print(a != b);   // true  不等于
print(a > b);    // false 大于
print(a < b);    // true  小于
print(a >= b);   // false 大于等于
print(a <= b);   // true  小于等于

// 逻辑运算符
bool x = true, y = false;
print(x && y);   // false 逻辑与
print(x || y);   // true  逻辑或
print(!x);       // false 逻辑非

// 类型判断运算符
var value = 'Hello';
print(value is String);     // true
print(value is! int);       // true

三、流程控制

3.1 条件语句

if分支和三元运算
// if-else
int score = 85;
if (score >= 90) {
  print('优秀');
} else if (score >= 60) {
  print('及格');
} else {
  print('不及格');
}

// 三元运算符
String result = score >= 60 ? '及格' : '不及格';

// 空值判断简写
String? name;
print(name ?? 'Guest');  // 等同于 name != null ? name : 'Guest'
switch_case
String grade = 'A';
switch (grade) {
  case 'A':
    print('优秀');
    break;
  case 'B':
    print('良好');
    break;
  case 'C':
    print('及格');
    break;
  default:
    print('不及格');
}

// Dart 3.0+ 支持增强的 switch 表达式
var result = switch (grade) {
  'A' => '优秀',
  'B' => '良好',
  'C' => '及格',
  _ => '不及格'
};

3.2 循环语句

while循环
// while 循环
int i = 0;
while (i < 5) {
  print(i);
  i++;
}

// do-while 循环(至少执行一次)
int j = 0;
do {
  print(j);
  j++;
} while (j < 5);
for循环
// 基本 for 循环
for (int i = 0; i < 5; i++) {
  print(i);
}

// for-in 循环
List<String> fruits = ['apple', 'banana', 'orange'];
for (var fruit in fruits) {
  print(fruit);
}

// forEach 方法
fruits.forEach((fruit) {
  print(fruit);
});

// break 和 continue
for (int i = 0; i < 10; i++) {
  if (i == 3) continue;  // 跳过3
  if (i == 8) break;     // 在8处停止
  print(i);
}

四、函数

4.1 函数基础

函数定义
// 基本函数定义
void sayHello() {
  print('Hello!');
}

// 有返回值的函数
String greet(String name) {
  return 'Hello, $name!';
}

// 简写(箭头函数,适用于单行表达式)
String greet2(String name) => 'Hello, $name!';

// 返回类型可选(不推荐省略)
add(int a, int b) {
  return a + b;
}
必传参数和可选位置参数
// 必传参数
int add(int a, int b) {
  return a + b;
}

// 可选位置参数(用 [] 包裹,可提供默认值)
String introduce(String name, [int? age, String city = 'Beijing']) {
  if (age != null) {
    return '$name, $age years old, from $city';
  }
  return '$name from $city';
}

// 调用示例
print(introduce('Alice'));              // Alice from Beijing
print(introduce('Bob', 25));            // Bob, 25 years old, from Beijing
print(introduce('Charlie', 30, 'Shanghai')); // Charlie, 30 years old, from Shanghai
可选命名参数
// 命名参数(用 {} 包裹)
void createUser({
  required String name,  // required 表示必传
  int age = 18,         // 有默认值
  String? email         // 可选,可为null
}) {
  print('Name: $name, Age: $age, Email: $email');
}

// 调用时使用参数名
createUser(name: 'Alice');
createUser(name: 'Bob', age: 25, email: 'bob@example.com');

// 命名参数的优点:顺序无关,更清晰
void setStyle({String? color, double? size, bool? bold}) {
  // ...
}
setStyle(bold: true, color: 'red');  // 顺序可以任意
匿名函数和箭头函数
// 匿名函数
var list = [1, 2, 3];
list.forEach((item) {
  print(item * 2);
});

// 箭头函数(单行表达式)
list.forEach((item) => print(item * 2));

// 将函数赋值给变量
var multiply = (int a, int b) => a * b;
print(multiply(3, 4));  // 12

// 函数作为参数
void executeOperation(int a, int b, Function operation) {
  print(operation(a, b));
}
executeOperation(5, 3, (a, b) => a + b);  // 8
executeOperation(5, 3, (a, b) => a * b);  // 15

// 闭包
Function makeAdder(int addBy) {
  return (int i) => i + addBy;
}
var add2 = makeAdder(2);
var add5 = makeAdder(5);
print(add2(3));  // 5
print(add5(3));  // 8

五、面向对象编程

5.1 类的基础

类的定义
class Person {
  String name;
  int age;
  
  // 方法
  void introduce() {
    print('I am $name, $age years old.');
  }
}

// 使用类
var person = Person();
person.name = 'Alice';
person.age = 25;
person.introduce();  // I am Alice, 25 years old.
类的默认构造函数
class Person {
  String name;
  int age;
  
  // 默认构造函数
  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  void introduce() {
    print('I am $name, $age years old.');
  }
}

// 使用
var person = Person('Bob', 30);
person.introduce();
类的命名构造函数
class Person {
  String name;
  int age;
  
  // 默认构造函数
  Person(this.name, this.age);
  
  // 命名构造函数
  Person.guest() {
    name = 'Guest';
    age = 0;
  }
  
  Person.fromJson(Map<String, dynamic> json) {
    name = json['name'];
    age = json['age'];
  }
}

// 使用命名构造函数
var guest = Person.guest();
var person = Person.fromJson({'name': 'Charlie', 'age': 28});
类构造函数的语法糖写法
class Person {
  String name;
  int age;
  String? email;
  
  // 语法糖:直接在参数列表中初始化
  Person(this.name, this.age, [this.email]);
  
  // 命名参数的语法糖
  Person.withEmail({
    required this.name,
    required this.age,
    this.email
  });
}

// 使用
var p1 = Person('Alice', 25);
var p2 = Person.withEmail(name: 'Bob', age: 30, email: 'bob@example.com');
类的公有属性和私有属性
class BankAccount {
  String accountNumber;    // 公有属性
  double _balance;         // 私有属性(以_开头)
  
  BankAccount(this.accountNumber, this._balance);
  
  // 公有方法
  double getBalance() {
    return _balance;
  }
  
  // 私有方法
  void _updateBalance(double amount) {
    _balance += amount;
  }
  
  void deposit(double amount) {
    if (amount > 0) {
      _updateBalance(amount);
    }
  }
  
  // Getter
  double get balance => _balance;
  
  // Setter
  set balance(double value) {
    if (value >= 0) {
      _balance = value;
    }
  }
}

// 使用
var account = BankAccount('123456', 1000);
print(account.balance);     // 使用getter:1000
account.deposit(500);
print(account.balance);     // 1500
account.balance = 2000;     // 使用setter

5.2 类的高级特性

类的继承
// 父类
class Animal {
  String name;
  
  Animal(this.name);
  
  void eat() {
    print('$name is eating');
  }
}

// 子类继承父类
class Dog extends Animal {
  String breed;
  
  // 调用父类构造函数
  Dog(String name, this.breed) : super(name);
  
  // 重写父类方法
  
  void eat() {
    print('$name the dog is eating dog food');
  }
  
  // 子类特有方法
  void bark() {
    print('$name is barking: Woof!');
  }
}

// 使用
var dog = Dog('Buddy', 'Golden Retriever');
dog.eat();   // Buddy the dog is eating dog food
dog.bark();  // Buddy is barking: Woof!
类的多态
class Animal {
  void makeSound() {
    print('Some sound');
  }
}

class Dog extends Animal {
  
  void makeSound() {
    print('Woof!');
  }
}

class Cat extends Animal {
  
  void makeSound() {
    print('Meow!');
  }
}

// 多态:父类引用指向子类对象
void animalSound(Animal animal) {
  animal.makeSound();
}

// 使用
animalSound(Dog());  // Woof!
animalSound(Cat());  // Meow!
抽象类和接口实现
// 抽象类(不能实例化)
abstract class Shape {
  // 抽象方法(没有方法体)
  double calculateArea();
  
  // 普通方法
  void display() {
    print('Area: ${calculateArea()}');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(this.radius);
  
  
  double calculateArea() {
    return 3.14 * radius * radius;
  }
}

// 接口实现(使用 implements)
class Rectangle implements Shape {
  double width;
  double height;
  
  Rectangle(this.width, this.height);
  
  
  double calculateArea() {
    return width * height;
  }
  
  
  void display() {
    print('Rectangle area: ${calculateArea()}');
  }
}

// 使用
Shape circle = Circle(5);
circle.display();  // Area: 78.5

Shape rect = Rectangle(4, 6);
rect.display();    // Rectangle area: 24.0
类的混入(Mixin)
// Mixin 定义
mixin Flyable {
  void fly() {
    print('Flying in the sky');
  }
}

mixin Swimmable {
  void swim() {
    print('Swimming in water');
  }
}

// 使用 with 关键字混入
class Duck extends Animal with Flyable, Swimmable {
  Duck(String name) : super(name);
  
  
  void eat() {
    print('$name is eating');
  }
}

// 使用
var duck = Duck('Donald');
duck.eat();   // Donald is eating
duck.fly();   // Flying in the sky
duck.swim();  // Swimming in water

5.3 泛型

泛型的使用
// 泛型类
class Box<T> {
  T value;
  
  Box(this.value);
  
  T getValue() {
    return value;
  }
}

// 使用泛型
var intBox = Box<int>(123);
var stringBox = Box<String>('Hello');
print(intBox.getValue());     // 123
print(stringBox.getValue());  // Hello

// 泛型函数
T getFirst<T>(List<T> list) {
  return list[0];
}

print(getFirst<int>([1, 2, 3]));        // 1
print(getFirst<String>(['a', 'b', 'c'])); // a

// 泛型约束
class NumberBox<T extends num> {
  T value;
  
  NumberBox(this.value);
  
  T add(T other) {
    return (value + other) as T;
  }
}

var numBox = NumberBox<int>(10);
print(numBox.add(5));  // 15

六、异步编程

6.1 Future

异步编程-事件循环

Dart 是单线程语言,使用事件循环(Event Loop)处理异步操作。

事件循环机制:

  1. 主线程(Microtask Queue):优先级最高
  2. 事件队列(Event Queue):处理 I/O、定时器等异步事件
void main() {
  print('1');
  
  // Future(Event Queue)
  Future(() => print('2'));
  
  // Microtask(优先级更高)
  scheduleMicrotask(() => print('3'));
  
  print('4');
}
// 输出顺序:1 4 3 2
Future的基本使用

Future 表示一个异步操作的最终完成(或失败)及其结果值。

// 创建 Future
Future<String> fetchData() {
  return Future.delayed(
    Duration(seconds: 2),
    () => 'Data loaded'
  );
}

// 使用 then 处理结果
void main() {
  print('Start');
  
  fetchData().then((data) {
    print(data);  // 2秒后输出:Data loaded
  });
  
  print('End');  // 立即输出
}
// 输出:Start End Data loaded

// 处理错误
Future<int> riskyOperation() {
  return Future.delayed(
    Duration(seconds: 1),
    () => throw Exception('Something went wrong!')
  );
}

riskyOperation()
  .then((value) => print('Success: $value'))
  .catchError((error) => print('Error: $error'))
  .whenComplete(() => print('Operation complete'));
Future的链式调用
Future<String> login(String username) {
  return Future.delayed(
    Duration(seconds: 1),
    () => 'Token_$username'
  );
}

Future<String> fetchUserInfo(String token) {
  return Future.delayed(
    Duration(seconds: 1),
    () => 'User info for $token'
  );
}

Future<List<String>> fetchPosts(String userInfo) {
  return Future.delayed(
    Duration(seconds: 1),
    () => ['Post 1', 'Post 2', 'Post 3']
  );
}

// 链式调用
void main() {
  login('alice')
    .then((token) {
      print('Logged in: $token');
      return fetchUserInfo(token);
    })
    .then((userInfo) {
      print('User info: $userInfo');
      return fetchPosts(userInfo);
    })
    .then((posts) {
      print('Posts: $posts');
    })
    .catchError((error) {
      print('Error: $error');
    });
}
Future的async和await

async/await 使异步代码看起来像同步代码,更易读易维护。

// 使用 async/await 改写上面的例子
Future<void> getUserData() async {
  try {
    print('Start loading...');
    
    // await 等待 Future 完成
    String token = await login('alice');
    print('Logged in: $token');
    
    String userInfo = await fetchUserInfo(token);
    print('User info: $userInfo');
    
    List<String> posts = await fetchPosts(userInfo);
    print('Posts: $posts');
    
    print('All done!');
  } catch (error) {
    print('Error: $error');
  }
}

void main() {
  getUserData();
}

// 多个异步操作并行执行
Future<void> loadMultipleData() async {
  // 并行执行多个异步操作
  var results = await Future.wait([
    fetchData1(),
    fetchData2(),
    fetchData3()
  ]);
  
  print('All data loaded: $results');
}

// async 函数必须返回 Future
Future<int> calculate() async {
  await Future.delayed(Duration(seconds: 1));
  return 42;
}

// 使用 async*
Stream<int> countStream(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;  // 生成值
  }
}

// 使用 Stream
void main() async {
  await for (var value in countStream(5)) {
    print(value);  // 每秒输出一个数字:1, 2, 3, 4, 5
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值