rust-code-quality-guide

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Rust Code Quality Guide

Rust代码质量指南

When to Use

适用场景

  • Writing new Rust code that requires type conversions or error handling
  • Reviewing Rust code for quality issues
  • Ensuring code follows best practices for error messages and Clippy compliance
  • Fixing Clippy warnings or understanding why certain patterns are discouraged
  • 编写需要类型转换或错误处理的新Rust代码
  • 评审Rust代码以排查质量问题
  • 确保代码遵循错误消息和Clippy合规性的最佳实践
  • 修复Clippy警告或理解为何某些模式不被推荐

Quick Reference

速查参考

  • as
    casting →
    try_from()
    +
    map_err()
  • unwrap_or(default)
    map_err()
    with explicit error
  • format!
    → use inline arguments
    {var}
  • Error messages must include the causative value
  • #[allow(clippy::...)]
    only allowed in test code

  • as
    类型转换 →
    try_from()
    +
    map_err()
  • unwrap_or(default)
    → 搭配显式错误的
    map_err()
  • format!
    → 使用内联参数
    {var}
  • 错误消息必须包含导致问题的具体值
  • #[allow(clippy::...)]
    仅允许在测试代码中使用

Code Quality Rules

代码质量规则

No Fallback for Type Conversion

类型转换禁止使用回退方案

CRITICAL: Never use
unwrap_or(MAX_VALUE)
or similar fallback methods for type conversions.
rust
// ❌ DANGEROUS - Silent failure with wrong value
let offset = u16::try_from(offset_value).unwrap_or(u16::MAX);

// ❌ DANGEROUS - Silent failure with wrong value (negative to zero)
let value_u8 = u8::try_from(value.max(0))
    .map_err(|_| "value exceeds u8::MAX")?;

// ❌ DANGEROUS - Silent failure with wrong value
let value = u8::try_from(negative_value).unwrap_or(0);

// ✅ SAFE - Explicit error handling
let offset = u16::try_from(offset_value)
    .map_err(|_| format!("offset {offset_value} exceeds u16::MAX"))?;

// ✅ SAFE - Explicit error handling (negative values cause error)
let value_u8 = u8::try_from(value)
    .map_err(|_| format!("value {value} must be between 0 and 255"))?;
Reason: Using
unwrap_or(MAX_VALUE)
,
max(0)
,
unwrap_or(0)
, or similar fallback methods can cause severe issues by silently mapping out-of-range or invalid values to default values, leading to incorrect calculations and potential system failures.
Rule: Always use proper error handling with
map_err
or explicit
match
statements for type conversions. Never silently convert invalid values (negative, out-of-range, etc.) to default values.
【严重】:绝不要在类型转换中使用
unwrap_or(MAX_VALUE)
或类似的回退方法。
rust
// ❌ 危险 - 无提示失败并返回错误值
let offset = u16::try_from(offset_value).unwrap_or(u16::MAX);

// ❌ 危险 - 无提示失败并返回错误值(负数转为0)
let value_u8 = u8::try_from(value.max(0))
    .map_err(|_| "value exceeds u8::MAX")?;

// ❌ 危险 - 无提示失败并返回错误值
let value = u8::try_from(negative_value).unwrap_or(0);

// ✅ 安全 - 显式错误处理
let offset = u16::try_from(offset_value)
    .map_err(|_| format!("offset {offset_value} exceeds u16::MAX"))?;

// ✅ 安全 - 显式错误处理(负数会触发错误)
let value_u8 = u8::try_from(value)
    .map_err(|_| format!("value {value} must be between 0 and 255"))?;
原因:使用
unwrap_or(MAX_VALUE)
max(0)
unwrap_or(0)
或类似回退方法会导致严重问题,它会将超出范围或无效的值无提示地映射为默认值,进而引发计算错误和潜在的系统故障。
规则:类型转换时始终使用
map_err
或显式
match
语句进行正确的错误处理。绝不要将无效值(负数、超出范围等)无提示地转换为默认值。

Inline Format Arguments

内联格式化参数

CRITICAL: Always use inline format arguments in
format!
macro to avoid Clippy warnings.
rust
// ❌ BAD - Causes clippy::uninlined_format_args warning
let message = format!("Error: {} occurred at line {}", error, line);

// ✅ GOOD - Use inline format arguments
let message = format!("Error: {error} occurred at line {line}");
Reason: Inline format arguments are more readable, performant, and avoid Clippy warnings.
Rule: Always use
{variable}
syntax instead of separate arguments in
format!
macro.
【严重】:在
format!
宏中始终使用内联格式化参数,以避免Clippy警告。
rust
// ❌ 不良写法 - 会触发clippy::uninlined_format_args警告
let message = format!("Error: {} occurred at line {}", error, line);

// ✅ 良好写法 - 使用内联格式化参数
let message = format!("Error: {error} occurred at line {line}");
原因:内联格式化参数可读性更强、性能更优,且能避免Clippy警告。
规则:在
format!
宏中始终使用
{variable}
语法,而非单独传入参数。

Include Causative Values in Error Messages

错误消息中包含导致问题的具体值

CRITICAL: Always include the actual parameter values that caused the error in error messages.
rust
// ❌ BAD - Generic error message without context
return Err("Invalid count".into());

// ✅ GOOD - Include the actual parameter value
return Err(format!("Invalid count: {count} (must be 1-474)").into());

// ✅ GOOD - Include multiple parameters for complex validation
return Err(format!("Range exceeds maximum: {start}-{end} (max 99)").into());
Reason: Including actual parameter values in error messages makes debugging significantly easier by providing immediate context about what went wrong.
Rule: Always include the actual parameter values that caused the error in error messages using inline format arguments.
【严重】:错误消息中必须始终包含引发错误的实际参数值。
rust
// ❌ 不良写法 - 无上下文的通用错误消息
return Err("Invalid count".into());

// ✅ 良好写法 - 包含实际参数值
return Err(format!("Invalid count: {count} (must be 1-474)").into());

// ✅ 良好写法 - 复杂验证时包含多个参数
return Err(format!("Range exceeds maximum: {start}-{end} (max 99)").into());
原因:在错误消息中包含实际参数值能提供直接的上下文,大幅简化调试工作。
规则:始终使用内联格式化参数,在错误消息中包含引发错误的实际参数值。

Use try_from() Instead of as

使用try_from()替代as类型转换

CRITICAL: Use
try_from()
instead of
as
casting for type conversions.
rust
// ❌ BAD - Silent truncation with as casting
let value = large_number as u8;

// ✅ GOOD - Explicit error handling with try_from
let value = u8::try_from(large_number)
    .map_err(|_| format!("Value {large_number} exceeds u8::MAX"))?;
Reason:
as
casting can silently truncate values, while
try_from()
provides explicit error handling for out-of-range conversions.
Rule: Use
try_from()
instead of
as
casting and implement proper error handling for type conversions.
【严重】:类型转换时使用
try_from()
替代
as
类型转换。
rust
// ❌ 不良写法 - as类型转换会无提示截断值
let value = large_number as u8;

// ✅ 良好写法 - 使用try_from()进行显式错误处理
let value = u8::try_from(large_number)
    .map_err(|_| format!("Value {large_number} exceeds u8::MAX"))?;
原因
as
类型转换会无提示截断值,而
try_from()
能为超出范围的转换提供显式错误处理。
规则:类型转换时使用
try_from()
替代
as
,并实现正确的错误处理。

No Clippy Suppression in Production Code

生产代码中禁止屏蔽Clippy警告

CRITICAL: Never use
#[allow(clippy::...)]
to suppress Clippy warnings in production code (non-test code).
rust
// ❌ BAD - Suppressing warnings in production code
#[allow(clippy::too_many_lines)]
pub async fn process_request(...) {
    // 100+ lines of code
}

// ✅ GOOD - Refactor the function to be smaller
pub async fn process_request(...) {
    // Call smaller helper functions
    handle_validation(...).await?;
}

async fn handle_validation(...) {
    // Smaller, focused function
}
Reason: Suppressing Clippy warnings hides code quality issues. Instead, refactor the code to address the underlying problem (e.g., split large functions, fix type issues, etc.).
Rule:
  • In production code: Always fix the underlying issue instead of suppressing warnings
  • In test code:
    #[allow(...)]
    is acceptable for test-specific patterns (e.g.,
    unwrap_used
    ,
    significant_drop_tightening
    )
  • If a warning cannot be reasonably fixed, document why with a comment explaining the exception
【严重】:绝不要在生产代码(非测试代码)中使用
#[allow(clippy::...)]
屏蔽Clippy警告。
rust
// ❌ 不良写法 - 在生产代码中屏蔽警告
#[allow(clippy::too_many_lines)]
pub async fn process_request(...) {
    // 100+行代码
}

// ✅ 良好写法 - 将函数重构为更小的模块
pub async fn process_request(...) {
    // 调用更小的辅助函数
    handle_validation(...).await?;
}

async fn handle_validation(...) {
    // 更小、职责单一的函数
}
原因:屏蔽Clippy警告会隐藏代码质量问题。相反,应重构代码以解决根本问题(例如,拆分大型函数、修复类型问题等)。
规则
  • 生产代码:始终修复根本问题,而非屏蔽警告
  • 测试代码:
    #[allow(...)]
    可用于测试特定模式(例如
    unwrap_used
    significant_drop_tightening
  • 如果某个警告确实无法合理修复,请添加注释说明例外原因