Menu
CoddyTech

用 fold 累加列表

本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 8 课,共 27 课。

费用列表需要求总和。你可以通过循环逐项相加,但列表有一个方法可以直接完成这件事:fold。它会遍历列表,把一个值从一项传递到下一项:

double total = expenses.fold(0.0, (sum, e) => sum + e.amount);

可以这样理解:从 0.0 开始。对于每笔费用 e,新的 sum 等于旧的 sum 加上 e.amount。遍历完列表后,最后的 sum 就是结果。对于 3.5 和 12,计算过程是 0.0,然后是 3.5,最后是 15.5。

这个函数必须返回新的总和。如果它只返回 e.amount,每一步都会忘记前一步的结果,“总和”就会变成最后一笔费用。

列表本身也可以改变:在 setState 中调用 expenses.add(...) 会再添加一项,下次构建时就会对新列表求和。

challenge icon

挑战

简单

总计这一行总是显示 $0.00。请改为计算总额:

  • 使用 expenses.fold 设置 total,将每笔支出的 amount 相加。

这一行已经显示 2 位小数,所以应显示为 Total: $15.50,添加零食后总额也会增加。

亲手试试

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class Expense {
  Expense({required this.name, required this.amount});

  final String name;
  final double amount;
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final List<Expense> expenses = [
    Expense(name: 'Coffee', amount: 3.5),
    Expense(name: 'Lunch', amount: 12),
  ];

  @override
  Widget build(BuildContext context) {
    double total = 0;
    return Scaffold(
      appBar: AppBar(title: const Text('Expenses')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            for (final e in expenses) Text('${e.name}: \$${e.amount.toStringAsFixed(2)}'),
            const SizedBox(height: 16),
            Text('Total: \$${total.toStringAsFixed(2)}', style: const TextStyle(fontSize: 28)),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  expenses.add(Expense(name: 'Snack', amount: 2.25));
                });
              },
              child: const Text('Add a snack'),
            ),
          ],
        ),
      ),
    );
  }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

状态管理中的所有课

自己练习: Flutter 在线编译器