Rust 编程指南·酷色篇 #06 - 条件与循环
theme: cyanosis

本章目标:掌握Rust条件判断和for循环,让颜色系统具备智能决策能力
条件判断,让程序拥有思考的艺术
想象一下,如果程序只会按部就班地执行代码,那该多么呆板!就像一个只会重复动作的机器人,永远不会根据情况做出调整。而条件判断就是给程序装上"大脑",让它能够观察、思考、决策。
在颜色世界中,条件判断更是无处不在:深色背景配浅色文字,浅色背景配深色文字;红色表示警告,绿色表示成功;根据时间切换主题色调…这些都需要程序具备"判断"的能力。
flowchart TD
A[颜色输入] --> B{条件判断}
B -->|亮度 > 128| C[使用深色文字]
B -->|亮度 ≤ 128| D[使用浅色文字]
B -->|红色分量高| E[警告样式]
B -->|绿色分量高| F[成功样式]
C --> G[智能颜色搭配]
D --> G
E --> G
F --> G
1. 用户痛点:颜色搭配的智能化需求
想象这个场景:你在设计一个界面,需要在不同颜色的背景上显示文字。如果背景是深色,文字就应该是浅色;如果背景是浅色,文字就应该是深色。手动调整每一个颜色搭配,既费时又容易出错。
痛苦的现状:
fn main() {
println!("=== 痛苦的现状:手动颜色搭配 ===");
// 每个背景色都要手动选择文字颜色
let bg1 = (30, 30, 30); // 深色背景
let text1 = (255, 255, 255); // 手动选择白色文字
let bg2 = (240, 240, 240); // 浅色背景
let text2 = (0, 0, 0); // 手动选择黑色文字
let bg3 = (100, 100, 100); // 中等亮度背景
let text3 = (255, 255, 255); // 这个选择对吗?
println!("背景1: {:?} -> 文字: {:?}", bg1, text1);
println!("背景2: {:?} -> 文字: {:?}", bg2, text2);
println!("背景3: {:?} -> 文字: {:?} (可能不够清晰)", bg3, text3);
println!("每次都要手动判断,太麻烦了!");
}
我们需要什么:

- 程序能自动判断背景亮度
- 根据亮度智能选择文字颜色
- 支持不同的颜色主题和风格
- 处理边界情况和特殊需求
2. Rust条件判断基础:if表达式的威力
什么是条件判断?
条件判断就像生活中的"如果…那么…"逻辑。比如:“如果下雨,那么带伞”、“如果饿了,那么吃饭”。在编程中,我们用这种逻辑让程序根据不同情况做出不同的反应。
Rust中的if特点:
if是表达式,不是语句,可以返回值- 条件必须是布尔类型,不会自动转换
- 所有分支必须返回相同类型的值
- 支持链式条件判断
基础if语法演示:
fn main() {
println!("\n=== Rust条件判断基础 ===");
let color_value = 128;
// 基础if语句
if color_value > 127 {
println!("这是一个亮色 ({})", color_value);
}
// if-else语句
if color_value > 127 {
println!("亮色:适合深色文字");
} else {
println!("暗色:适合浅色文字");
}
// if作为表达式(Rust特色)
let text_color = if color_value > 127 {
"黑色文字" // 亮背景用深色文字
} else {
"白色文字" // 暗背景用浅色文字
};
println!("背景亮度: {} -> 推荐文字: {}", color_value, text_color);
}
重要概念解释:
- 表达式 vs 语句:表达式有返回值,语句执行动作
- 布尔类型:只有
true和false两个值 - 类型一致性:if和else分支必须返回相同类型
3. 颜色亮度计算:智能判断的基础
亮度计算的科学原理:
人眼对不同颜色的敏感度不同,绿色最敏感,红色次之,蓝色最不敏感。因此计算亮度时需要加权处理,而不是简单的平均值。
标准亮度公式:亮度 = 0.299 × R + 0.587 × G + 0.114 × B
// 计算颜色亮度的函数
fn calculate_brightness(rgb: (u8, u8, u8)) -> f32 {
let (r, g, b) = rgb;
// 使用标准亮度公式,考虑人眼敏感度
0.299 * r as f32 + 0.587 * g as f32 + 0.114 * b as f32
}
// 简化版本(适合初学者理解)
fn simple_brightness(rgb: (u8, u8, u8)) -> u8 {
let (r, g, b) = rgb;
// 简单平均值计算
((r as u16 + g as u16 + b as u16) / 3) as u8
}
fn main() {
println!("=== 颜色亮度计算演示 ===");
let colors = vec![
("纯黑", (0, 0, 0)),
("深灰", (64, 64, 64)),
("中灰", (128, 128, 128)),
("浅灰", (192, 192, 192)),
("纯白", (255, 255, 255)),
("纯红", (255, 0, 0)),
("纯绿", (0, 255, 0)),
("纯蓝", (0, 0, 255)),
];
for (name, rgb) in colors {
let brightness = calculate_brightness(rgb);
let simple = simple_brightness(rgb);
println!("{}: RGB{:?}", name, rgb);
println!(" 标准亮度: {:.1}", brightness);
println!(" 简单亮度: {}", simple);
println!();
}
}
代码解释:
- 类型转换:
as f32将整数转换为浮点数进行精确计算 - 元组解构:
let (r, g, b) = rgb一次性获取三个颜色分量 - 权重计算:不同颜色分量使用不同的权重系数
4. 智能文字颜色选择:条件判断实战
现在我们来解决开头的痛点,用条件判断实现智能的文字颜色选择:
// 智能选择文字颜色
fn choose_text_color(background: (u8, u8, u8)) -> (u8, u8, u8) {
let brightness = calculate_brightness(background);
// 亮度阈值:128是中间值
if brightness > 128.0 {
(0, 0, 0) // 亮背景用黑色文字
} else {
(255, 255, 255) // 暗背景用白色文字
}
}
// 更精细的文字颜色选择
fn smart_text_color(background: (u8, u8, u8)) -> (u8, u8, u8) {
let brightness = calculate_brightness(background);
if brightness > 200.0 {
(0, 0, 0) // 很亮:纯黑文字
} else if brightness > 128.0 {
(64, 64, 64) // 较亮:深灰文字
} else if brightness > 64.0 {
(192, 192, 192) // 较暗:浅灰文字
} else {
(255, 255, 255) // 很暗:纯白文字
}
}
// 显示颜色搭配效果
fn display_color_match(background: (u8, u8, u8), text: (u8, u8, u8), label: &str) {
let (bg_r, bg_g, bg_b) = background;
let (txt_r, txt_g, txt_b) = text;
// 使用ANSI码显示背景色和文字色的搭配效果
print!("\x1b[48;2;{};{};{}m", bg_r, bg_g, bg_b); // 设置背景色
print!("\x1b[38;2;{};{};{}m", txt_r, txt_g, txt_b); // 设置文字色
print!(" {} ", label);
print!("\x1b[0m"); // 重置颜色
println!(" 背景RGB({},{},{}) -> 文字RGB({},{},{})",
bg_r, bg_g, bg_b, txt_r, txt_g, txt_b);
}
fn main() {
println!("=== 智能文字颜色选择演示 ===");
let test_backgrounds = vec![
("深夜黑", (20, 20, 20)),
("炭灰色", (80, 80, 80)),
("中性灰", (128, 128, 128)),
("银白色", (200, 200, 200)),
("纯白色", (255, 255, 255)),
("深蓝色", (0, 50, 100)),
("亮黄色", (255, 255, 100)),
];
println!("1. 基础智能选择:");
for (name, bg_color) in &test_backgrounds {
let text_color = choose_text_color(*bg_color);
display_color_match(*bg_color, text_color, name);
}
println!("\n2. 精细智能选择:");
for (name, bg_color) in &test_backgrounds {
let text_color = smart_text_color(*bg_color);
display_color_match(*bg_color, text_color, name);
}
}
关键技术点:
- 多级条件判断:使用
else if实现更精细的控制 - 阈值设计:选择合适的亮度阈值来区分不同情况
- 视觉反馈:通过ANSI颜色码直观展示搭配效果
5. 颜色状态判断:布尔逻辑的应用
布尔逻辑在颜色中的应用:
在颜色处理中,我们经常需要判断颜色的各种状态和属性,这就需要用到布尔逻辑运算。

// 颜色属性判断函数集合
fn is_dark_color(rgb: (u8, u8, u8)) -> bool {
calculate_brightness(rgb) < 128.0
}
fn is_light_color(rgb: (u8, u8, u8)) -> bool {
calculate_brightness(rgb) > 128.0
}
fn is_grayscale(rgb: (u8, u8, u8)) -> bool {
let (r, g, b) = rgb;
r == g && g == b // 三个分量相等就是灰度色
}
fn is_warm_color(rgb: (u8, u8, u8)) -> bool {
let (r, g, b) = rgb;
r > g && r > b // 红色分量最大
}
fn is_cool_color(rgb: (u8, u8, u8)) -> bool {
let (r, g, b) = rgb;
b > r && b > g // 蓝色分量最大
}
fn is_high_contrast(bg: (u8, u8, u8), fg: (u8, u8, u8)) -> bool {
let bg_brightness = calculate_brightness(bg);
let fg_brightness = calculate_brightness(fg);
(bg_brightness - fg_brightness).abs() > 100.0 // 亮度差大于100
}
// 复合条件判断
fn analyze_color_properties(rgb: (u8, u8, u8)) -> String {
let mut properties = Vec::new();
// 使用多个布尔判断
if is_dark_color(rgb) {
properties.push("深色");
} else {
properties.push("浅色");
}
if is_grayscale(rgb) {
properties.push("灰度");
} else if is_warm_color(rgb) {
properties.push("暖色调");
} else if is_cool_color(rgb) {
properties.push("冷色调");
} else {
properties.push("中性色调");
}
properties.join(" + ")
}
fn main() {
println!("=== 颜色属性判断演示 ===");
let test_colors = vec![
("深红色", (139, 0, 0)),
("天蓝色", (135, 206, 235)),
("中灰色", (128, 128, 128)),
("亮黄色", (255, 255, 0)),
("深紫色", (75, 0, 130)),
("浅粉色", (255, 182, 193)),
];
for (name, color) in test_colors {
println!("\n{}: RGB{:?}", name, color);
println!(" 属性分析: {}", analyze_color_properties(color));
println!(" 是否深色: {}", is_dark_color(color));
println!(" 是否灰度: {}", is_grayscale(color));
println!(" 是否暖色: {}", is_warm_color(color));
// 测试对比度
let white = (255, 255, 255);
let black = (0, 0, 0);
println!(" 与白色对比度: {}", is_high_contrast(color, white));
println!(" 与黑色对比度: {}", is_high_contrast(color, black));
}
}
布尔逻辑运算符:
&&- 逻辑与(AND):两个条件都为真||- 逻辑或(OR):至少一个条件为真!- 逻辑非(NOT):取反==- 相等比较!=- 不等比较>,<,>=,<=- 大小比较
6. 简单渐变文字:条件判断与循环的初步结合
渐变效果的魅力:
想象一下,如果我们能让文字呈现渐变色彩,那该多么有趣!通过结合条件判断和for循环,我们可以为每个字符计算不同的颜色。

核心知识点:
- for循环遍历:逐个处理字符串中的每个字符
- enumerate():同时获取索引和元素
- 条件分类:根据字符类型应用不同颜色
- ANSI转义码:在终端中显示彩色效果
// 简单的RGB渐变文字函数
fn simple_gradient_text(text: &str) {
let chars: Vec<char> = text.chars().collect();
let len = chars.len();
for (i, ch) in chars.iter().enumerate() {
// 计算进度比例(0.0 到 1.0)
let progress = i as f32 / len as f32;
// 简单的红到蓝渐变
let r = (255.0 * (1.0 - progress)) as u8; // 红色逐渐减少
let g = 100; // 绿色保持不变
let b = (255.0 * progress) as u8; // 蓝色逐渐增加
// 使用条件判断处理特殊字符
if ch.is_whitespace() {
print!(" "); // 空格保持原样
} else {
print!("\x1b[38;2;{};{};{}m{}", r, g, b, ch);
}
}
println!("\x1b[0m"); // 重置颜色
}
// 根据字符类型选择颜色
fn colored_by_type(text: &str) {
for ch in text.chars() {
// 根据字符类型使用不同颜色
let (r, g, b) = if ch.is_ascii_alphabetic() {
(0, 255, 0) // 字母用绿色
} else if ch.is_ascii_digit() {
(0, 100, 255) // 数字用蓝色
} else if ch.is_ascii_punctuation() {
(255, 215, 0) // 标点用金色
} else {
(255, 255, 255) // 其他用白色
};
if ch.is_whitespace() {
print!(" ");
} else {
print!("\x1b[38;2;{};{};{}m{}", r, g, b, ch);
}
}
println!("\x1b[0m");
}
fn main() {
println!("=== 🌈 简单渐变文字演示 ===");
let welcome_text = "欢迎来到 Rust 世界";
println!("\n1. 简单RGB渐变:");
simple_gradient_text(welcome_text);
println!("\n2. 按类型着色:");
colored_by_type("Hello123, Rust编程! 2024年");
println!("\n3. 条件判断在循环中的应用:");
let test_text = "Code123!代码";
print!("原文: {}", test_text);
println!();
print!("彩色: ");
colored_by_type(test_text);
}
代码要点解析:
1. 简单渐变算法
let progress = i as f32 / len as f32; // 计算进度比例
let r = (255.0 * (1.0 - progress)) as u8; // 红色逐渐减少
let b = (255.0 * progress) as u8; // 蓝色逐渐增加
- 进度计算:将字符位置转换为0-1的比例
- 线性插值:使用简单的数学公式实现颜色过渡
- 类型转换:
as u8将浮点数转为整数
2. 字符类型判断
if ch.is_ascii_alphabetic() {
(0, 255, 0) // 字母用绿色
} else if ch.is_ascii_digit() {
(0, 100, 255) // 数字用蓝色
}
- 分类函数:使用Rust内置的字符分类函数
- 颜色策略:为不同类型的字符分配不同颜色
- 默认处理:为未匹配的情况提供白色
3. ANSI转义码使用
print!("\x1b[38;2;{};{};{}m{}", r, g, b, ch);
println!("\x1b[0m"); // 重置颜色
- 真彩色输出:24位RGB颜色
- 格式重置:确保颜色不会影响后续输出
实际应用:
- 终端工具的彩色输出
- 日志级别区分
- 代码语法高亮
条件判断与循环的结合:
- 循环遍历 - 使用for循环处理每个字符
- 条件分支 - 根据字符类型选择不同处理
- 数学计算 - 使用简单公式实现渐变效果
- 视觉反馈 - 通过颜色变化展示程序逻辑
这个简单的例子展示了条件判断在实际应用中的强大能力,同时为下一章的循环学习做了很好的铺垫!
本章核心要点
条件判断的价值:
- 智能决策 - 让程序根据情况做出不同反应
- 用户体验 - 自动优化颜色搭配,提升可读性
- 逻辑控制 - 实现复杂的业务逻辑和流程控制
- 系统灵活性 - 支持多种模式和个性化设置
Rust条件判断特色:
- 表达式特性 - if可以返回值,代码更简洁
- 类型安全 - 条件必须是布尔类型,避免隐式转换
- 模式匹配 - 为复杂条件判断提供更优雅的解决方案
- 零成本抽象 - 编译时优化,运行时无额外开销
通过本章学习,你已经掌握了让程序"思考"的能力!条件判断是编程逻辑的基础,接下来我们将学习如何让程序"重复工作" - 循环控制。
更多文章和视频知识资讯,大家可以关注我的公众号、掘金和 B 站 。让我们一起成长,变得更强。我们下次再见~
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)