增强 for 循环
本课属于 Coddy Rust 学习旅程的“基础知识”单元。第 66 课,共 75 课。
遍历数组有多种方法,下面介绍其中几种:
请看下面这个数组:
let numbers = [1, 2, 3, 4, 5];直接迭代器:
for num in numbers.iter() {} // 值:1, 2, 3, 4, 5
索引和数值:
for (index, value) in numbers.iter().enumerate() { } // 值:(0,1)、(1,2)、(2,3)、(3,4)、(4,5)
指定大小的切片:
for chunk in numbers.chunks(2) { } // 值:[1,2]、[3,4]、[5]每个块都是一个切片,因此你可以对它使用切片方法,例如,
chunk.len()会返回该块中的元素数量。如果数组不能被均匀分组,最后一个块可能会更小。
你也可以将 .enumerate() 链接到 .chunks() 后面,同时获取索引和数据块:
for (i, chunk) in numbers.chunks(2).enumerate() { }
// 值:(0,[1,2]), (1,[3,4]), (2,[5])这里,.chunks(2) 会先生成切片,然后 .enumerate() 为每个切片添加一个计数器,因此 i 是数据块的索引,而 chunk 是切片。
通过修改进行迭代:
let mut numbers = [1, 2, 3, 4, 5]; for num in numbers.iter_mut() { *num *= 2; } // 数组变为:[2, 4, 6, 8, 10]
挑战
简单编写一个程序,处理包含商品及其价格的购物列表,并以不同方式展示数据。
程序应当:
- 打印每件商品的编号和价格(使用
enumerate)。格式为Item N: $Price(例如:Item 1: $2.75)。 - 将价格两两配对(使用
chunks),作为“捆绑优惠”打印。如果一组中有 2 件商品,就打印总价:Bundle N: $Price1 + $Price2 = $Sum。如果只有 1 件商品,就打印:Bundle N: $Price。 - 给所有价格打 10% 的折扣(使用
iter_mut)。 - 打印折扣后的最终价格,每个价格单独占一行,并格式化为保留 2 位小数(例如:
$2.48)。
提示:你可以将迭代器串联起来,例如,prices.chunks(2).enumerate() 会同时提供每组的索引和切片。每个 chunk 都是一个切片,因此你可以对它调用 chunk.len(),也可以使用 chunk[0]、chunk[1] 等访问其中的元素。
价格的预期输出格式:
使用 ${:.2} 将价格格式化为保留 2 位小数。
准确文本为 Bundle 4: $7.90。
亲手试试
fn main() {
let mut prices = [2.75, 1.50, 5.00, 3.5, 4.1, 2.25, 7.9];
println!("Original Prices:");
// TODO:使用 enumerate() 打印每件商品的编号和价格
// 提示:prices.iter().enumerate() 会生成 (index, &price) 元组
// 使用 {:.2} 将价格格式化为保留 2 位小数,具体格式请参照说明
println!("\nBundle Deals:");
// TODO:将 chunks(2) 和 enumerate() 串联起来:prices.chunks(2).enumerate()
// 这会生成 (index, chunk) 元组。每个 chunk 都是一个切片,因此 chunk.len() 可以告诉你它的大小
// 如果 chunk.len() == 2,打印:"Bundle 1: $2.75 + $1.50 = $4.25"
// 如果 chunk.len() == 1,打印说明中描述的单件商品那一行
// 使用 {:.2} 将所有价格格式化为保留 2 位小数
// TODO:使用 iter_mut() 对所有价格应用 10% discount
// 提示:将每个 *price 乘以 0.9
println!("\nPrices after 10% discount:");
// TODO:打印每个折后价格,保留 2 位小数
// 预期输出格式见说明
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Rust 在线编译器