控制流语句用于控制程序执行的顺序,允许程序根据条件选择不同的执行路径,或者重复执行某些代码块。Dart 提供了多种控制流语句,包括条件语句(if-else、switch-case)和循环语句(for、while、do-while)。
1. 条件语句
if 和 else
if 语句用于根据条件执行代码块。如果条件为 true,则执行 if 块中的代码;否则,如果存在 else 块,则执行 else 块中的代码。可以使用 else if 来检查多个条件。
int score = 85;
if (score >= 90) {
print("优秀");
} else if (score >= 60) {
print("及格");
} else {
print("不及格");
}
switch 和 case
switch 语句用于根据表达式的值选择多个执行路径中的一个。每个 case 后面跟着一个值,如果表达式的值与 case 的值匹配,则执行该 case 块中的代码。break 语句用于跳出 switch 语句。default 关键字用于处理所有 case 都不匹配的情况。
String command = "OPEN";
switch (command) {
case "OPEN":
print("打开文件");
break;
case "SAVE":
print("保存文件");
break;
case "CLOSE":
print("关闭文件");
break;
default:
print("未知命令");
}
2. 循环语句
for 循环
for 循环用于重复执行代码块指定次数。它通常包含初始化、条件和递增/递减表达式。
for (int i = 0; i < 5; i++) {
print("循环次数: $i");
}
// for-in 循环用于遍历集合
List<String> fruits = ["apple", "banana", "orange"];
for (String fruit in fruits) {
print("水果: $fruit");
}
while 循环
while 循环在条件为 true 时重复执行代码块。在每次循环迭代之前检查条件。
int count = 0;
while (count < 3) {
print("计数: $count");
count++;
}
do-while 循环
do-while 循环与 while 循环类似,但它至少会执行一次代码块,然后在每次循环迭代之后检查条件。
int i = 0;
do {
print("执行一次,i = $i");
i++;
} while (i < 0); // 条件为 false,但循环体至少执行一次
3. break 和 continue 语句
break: 用于立即终止循环或 switch 语句的执行,并跳到循环或 switch 之后的语句。
continue: 用于跳过当前循环迭代的剩余部分,并开始下一次迭代。
for (int i = 0; i < 10; i++) {
if (i == 3) {
continue; // 跳过 3
}
if (i == 7) {
break; // 终止循环
}
print(i);
}
// 输出: 0, 1, 2, 4, 5, 6
控制流语句在 Flutter 应用中扮演着核心角色,它们用于根据用户交互、数据状态或业务逻辑来动态地构建 UI、处理事件和管理应用流程。
案例:一个动态列表的构建与筛选
我们将创建一个简单的 Flutter 应用,展示一个商品列表,并允许用户根据条件进行筛选。这个案例将演示 if-else、for-in 循环以及 switch 语句在 Flutter UI 构建中的应用。
import 'package:flutter/material.dart';
class Product {
final String name;
final double price;
final String category;
Product({required this.name, required this.price, required this.category});
}
class ProductListScreen extends StatefulWidget {
const ProductListScreen({super.key});
@override
State<ProductListScreen> createState() => _ProductListScreenState();
}
class _ProductListScreenState extends State<ProductListScreen> {
List<Product> _allProducts = [
Product(name: '苹果', price: 5.0, category: '水果'),
Product(name: '香蕉', price: 3.0, category: '水果'),
Product(name: '牛奶', price: 12.0, category: '乳制品'),
Product(name: '面包', price: 8.0, category: '烘焙'),
Product(name: '酸奶', price: 10.0, category: '乳制品'),
Product(name: '蛋糕', price: 25.0, category: '烘焙'),
];
String _selectedCategory = '所有';
List<Product> get _filteredProducts {
if (_selectedCategory == '所有') {
return _allProducts;
} else {
// 使用 for-in 循环和 if 条件进行筛选
List<Product> filtered = [];
for (var product in _allProducts) {
if (product.category == _selectedCategory) {
filtered.add(product);
}
}
return filtered;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('商品列表'),
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButton<String>(
value: _selectedCategory,
onChanged: (String? newValue) {
setState(() {
_selectedCategory = newValue!;
});
},
items: <String>['所有', '水果', '乳制品', '烘焙']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
Expanded(
child: ListView.builder(
itemCount: _filteredProducts.length,
itemBuilder: (context, index) {
final product = _filteredProducts[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
product.name,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text('价格: ¥${product.price.toStringAsFixed(2)}'),
Text('分类: ${product.category}'),
// 根据分类使用 switch 语句显示不同图标
Builder(
builder: (context) {
IconData iconData;
switch (product.category) {
case '水果':
iconData = Icons.apple;
break;
case '乳制品':
iconData = Icons.local_drink;
break;
case '烘焙':
iconData = Icons.cake;
break;
default:
iconData = Icons.category;
}
return Icon(iconData);
},
),
],
),
),
);
},
),
),
],
),
);
}
}
void main() {
runApp(const MaterialApp(home: ProductListScreen()));
}
案例分析:
if-else 语句:在 _filteredProducts getter 中,if (_selectedCategory == '所有') 用于判断是否显示所有商品,否则进入 else 块进行筛选。这展示了如何根据条件动态地改变数据源。for-in 循环:在 else 块中,for (var product in _allProducts) 用于遍历所有商品,并结合 if (product.category == _selectedCategory) 条件语句来筛选出符合条件的商品。这在处理列表数据时非常常用。switch 语句:在 itemBuilder 中,我们使用 switch (product.category) 来根据商品的分类显示不同的图标。这是一种清晰地处理多分支条件逻辑的方式。ListView.builder: Flutter 中用于构建长列表的 Widget,它会根据 itemCount 和 itemBuilder 动态地渲染列表项。itemBuilder 内部的逻辑(包括对 product 属性的访问和 switch 语句的使用)直接影响 UI 的呈现。DropdownButton: 这是一个下拉菜单 Widget,onChanged 回调函数中会更新 _selectedCategory 的值,并通过 setState 触发 UI 重建,从而使 _filteredProducts 重新计算并更新列表显示。这个案例清晰地展示了 Dart 的控制流语句如何在 Flutter 应用中用于实现数据筛选、UI 动态更新和条件渲染。掌握这些语句是构建交互式和响应式 Flutter 应用的关键。