一、核心规则对比 (编译器/解释器强制要求)
方面 | Rust 🦀 | Python 🐍 | 说明 |
---|---|---|---|
字符集 | 必须以字母或下划线 _ 开头。后续字符可以是字母、数字、下划线 _。 | 必须以字母或下划线 _ 开头。后续字符可以是字母、数字、下划线 _。 | 基本规则完全相同。 |
Unicode 支持 | 支持。可以使用 字 或 emoji🎉 作为标识符,但极度不推荐。 | 支持(Python 3+)。同样可以使用非 ASCII 字符,但也强烈不推荐。 | 都支持,但都强烈建议只使用 ASCII 字符以保证可读性和可维护性。 |
长度限制 | 无限制。 | 无限制。 | 相同。 |
关键字冲突 | 不允许使用关键字(如 fn, let, struct)作为标识符。 | 不允许使用关键字(如 def, class, if)作为标识符。 | 相同。通常可以通过后缀 _ 来规避(如 let struct_ = …;)。 |
严格性 | 非常严格。违反规则会导致编译错误。 | 非常严格。违反规则会导致 SyntaxError。 | 两者都是强制的硬性规定。 |
小结:在核心语法规则上,Rust 和 Python 几乎完全一致。
二、命名风格惯例 (社区约定,非强制但强烈推荐)
这是两者差异最大的地方。不同的哲学导致了截然不同的代码风格。
标识符类型 | Rust 官方惯例 (rustfmt) | Python 官方惯例 (PEP 8) | 对比说明 |
---|---|---|---|
变量/函数/方法名 | snake_case let user_name;fn calculate_area() | snake_case user_name = “” def calculate_area(): | 两者在此达成一致。都使用全小写+下划线的蛇形命名法。 |
常量名 | SCREAMING_SNAKE_CASE const MAX_USERS: u32 = 100; | SCREAMING_SNAKE_CASE MAX_USERS = 100 | 两者再次一致。都使用全大写+下划线的 screaming snake case。 |
类型名 | |||
(类/结构体/枚举/特质) | PascalCase struct UserProfile { … } enum HttpStatus { … } trait DataSerializer { … } | PascalCase class UserProfile: … class HttpStatus: … (Python 中枚举也常用 PascalCase) | 两者一致。都使用帕斯卡命名法(大驼峰)。 |
模块名 | snake_case mod network_utils; use std::path; | snake_case import requests from os import path | 两者一致。模块文件名和导入名都使用蛇形命名。 |
函数参数 | snake_case fn greet_user(user_name: &str) | snake_case def greet_user(user_name): | 两者一致。 |
“私有”标识符 | snake_case,但通过 pub 关键字控制可见性。没有命名约定。 | _single_leading_underscore _internal_use_only 这是一个“弱内部使用”提示。 | 关键差异。Python 使用前置下划线作为命名约定来表示“私有”。Rust 完全依赖语言关键字 (pub),命名上不做区分。 |
特殊方法 | snake_case 特质方法(如 fmt::Display 的 fn fmt(…)) | dunder__methods init, str, len | 巨大差异。Python 使用双下划线(dunder)包裹的特殊方法名。Rust 则使用普通的蛇形命名,通过实现特定的特质(Trait)来达到类似效果。 |
宏名 | snake_case! println!(), vec![] | N/A | Rust 的宏在命名上看起来像函数,但以 ! 结尾。Python 没有真正的宏。 |
三、示例代码对比
变量与函数
Rust
// 变量、函数:snake_case
let first_name = "Alice";
const MAX_LOGIN_ATTEMPTS: u8 = 3;
fn get_user_by_id(user_id: u64) -> User {
// ...
}
Python
# 变量、函数:snake_case
first_name = "Alice"
MAX_LOGIN_ATTEMPTS = 3
def get_user_by_id(user_id):
# ...
pass
类型定义
Rust
// 结构体、枚举、特质:PascalCase
struct UserSettings {
is_private: bool,
language: String,
}
enum PaymentStatus {
Pending,
Completed,
Failed,
}
trait JsonSerializable {
fn to_json(&self) -> String;
}
Python
# 类:PascalCase
class UserSettings:
def __init__(self, is_private, language):
self.is_private = is_private
self.language = language
# 枚举(需要导入enum模块)
from enum import Enum
class PaymentStatus(Enum):
PENDING = 1
COMPLETED = 2
FAILED = 3
“私有”性表示
Rust
// Rust 使用 `pub` 关键字,命名无区别
mod network {
pub fn public_api() { ... } // 外部可调用
fn internal_helper() { ... } // 仅模块内可调用,命名上没有提示
}
Python
# Python 使用前置下划线约定
class Database:
def __init__(self):
self._connection = None # “保护”成员,提示外部不要直接访问
self.__secret_key = "abc" # “私有”成员(名称修饰,并非真正私有)
def public_method(self):
self._internal_helper() # “保护”方法
def _internal_helper(self): # 提示为内部使用
pass
四、总结与关键差异
特性 | Rust 🦀 | Python 🐍 | 结论 |
---|---|---|---|
哲学 | 形式重于约定。可见性由语言关键字 (pub) 严格强制执行,命名风格主要用于可读性。 | 约定重于形式。使用命名约定(如 _leading_underscore)来提示意图和“私有性”,但无法真正强制。 | Rust 的方式更严格、更安全;Python 的方式更灵活,但依赖程序员的自觉。 |
一致性 | 极高。官方工具 rustfmt 会自动格式化代码以符合约定,生态高度统一。 | 很高。PEP 8 是权威指南,工具(如 black, autopep8)可以自动格式化,社区广泛遵循。 | 两者都拥有强大且一致的风格文化。 |
特殊方法 | 普通的 snake_case,通过实现特质(Trait)来定义行为。 | 独特的 dunder 风格,是语言语法的一部分。 | Rust 的特质系统更为通用和强大;Python 的 dunder 方法更直观地集成在类中。 |
最关键差异 | 没有“私有”命名约定,全靠 pub 关键字。 | 使用 _ 和 __ 作为“私有”命名约定。 | 这是从一种语言切换到另一种语言时最需要适应的点。 |
简单记忆:
Rust: 什么都用 snake_case,除了类型用 PascalCase 和常量用 SCREAMING_SNAKE_CASE。没有私有命名约定。
Python: 什么都用 snake_case,除了类型用 PascalCase 和常量用 SCREAMING_SNAKE_CASE。有私有命名约定 (_ 和 __)。