Rust 与 C# 语法差异详细对比

作为从 C# 转向 Rust 的开发者,理解两者语法设计的核心差异有助于快速适应。以下从基础语法、核心特性到高级功能进行对比,并结合搜索结果中的技术特性分析:

一、基础语法对比


语法维度C#Rust关键差异
变量声明int x = 5;var x = 5; (类型推断)let x = 5; (不可变) 或 let mut x = 5; (可变)Rust 变量默认不可变,需显式用 mut 声明可变变量;C# 默认允许修改 5
函数定义public int Add(int a, int b) { ... }fn add(a: i32, b: i32) -> i32 { ... }Rust 函数参数需显式标注类型,返回值用 -> 类型 声明;C# 支持隐式类型推断 5
全局函数仅允许在静态类中定义 (如 static class Utils { ... })直接支持全局函数 (无需类包裹)Rust 无需类/命名空间包裹顶层函数,C# 严格依赖类结构 5
函数重载支持 (通过参数类型/数量区分)不支持 (需通过不同函数名或泛型实现)C# 支持函数重载,Rust 需显式命名不同函数(如 add_i32/add_f645
入口函数static void Main(string[] args) { ... }fn main() { ... } 或带参数 fn main(args: Vec<String>) { ... }Rust 入口函数更简洁,参数通过 std::env::args 获取。

二、核心特性对比

1. 类型系统


特性C#Rust说明
基本类型int/string/bool 等,值类型/引用类型分离i32/String/bool 等,无值类型/引用类型概念Rust 通过所有权系统管理内存,而非 C# 的值类型(栈)/引用类型(堆)二分法 1
字符串类型string (引用类型,UTF-16 编码)String (堆分配) / &str (字符串切片,UTF-8 编码)Rust 区分动态字符串 String 和静态字符串切片 &str,C# 统一为 string
泛型List<T> 等,支持泛型约束Vec<T> 等,泛型约束更严格 (如 T: Trait)两者均支持泛型,但 Rust 泛型需通过 trait 约束,C# 用 where 子句 5

2. 内存管理与安全性


特性C#Rust说明
内存管理垃圾回收 (GC) 自动管理编译期所有权系统 (无 GC)C# 依赖 GC 回收内存,Rust 通过所有权/借用规则在编译期确保内存安全,无运行时开销 1
空值处理允许 null (引用类型默认可空)显式通过 Option<T> 枚举处理 (非空安全)Rust 无 null,需用 Option::Some(value)/Option::None 表示可能为空的值,编译期避免空指针异常 1
悬垂引用可能出现 (如 var x = new object(); x = null; 后引用失效)编译期禁止 (通过借用规则确保引用有效)Rust 的借用检查器(Borrow Checker)杜绝悬垂引用,C# 需手动避免空引用 1

3. 控制流与模式匹配


特性C#Rust说明
条件表达式if (condition) { ... } else { ... }if condition { ... } else { ... }语法类似,但 Rust 允许 if 作为表达式返回值(如 let x = if a > b { 1 } else { 0 };)。
模式匹配switch 语句 (C# 8.0+ 支持模式匹配)match 表达式 (功能更强大)Rust match 支持枚举、结构体、范围等复杂模式,且强制覆盖所有可能分支(无 default 时)。
循环for/while/do-whilefor/while/loop (无限循环)Rust 无 do-while,可用 loop { ... if condition { break; } } 替代。

4. 错误处理


C# 方式Rust 方式核心差异
try-catch 异常捕获Result<T, E> 枚举 + ? 运算符C# 通过异常传递错误,Rust 通过返回 Result 类型显式处理,编译期强制检查未处理错误 1
throw new Exception("错误")Err(MyError::Message("错误".to_string()))Rust 错误是值而非异常,需显式返回;C# 异常会中断执行流。
可忽略异常 (不推荐)unwrap() (强制解包,出错时崩溃) 或 expect("提示")Rust 鼓励显式处理错误,unwrap 仅用于原型开发。

三、高级功能对比

1. 面向对象与 trait 抽象


C# 特性Rust 对应实现说明
类继承 (class B : A { ... })组合 + trait 实现 (struct B { a: A } + impl Trait for B { ... })Rust 无类继承,通过 trait 定义接口,结构体通过 impl Trait 添加行为 1
接口 (interface IMyInterface { ... })trait (trait MyTrait { ... })Rust trait 可包含默认方法实现,C# 接口需显式实现。
虚方法 (virtual/override)trait 方法覆盖Rust 通过 impl Trait for Type 重写 trait 方法,无运行时多态开销。

2. 泛型与模板

| C# 泛型 | Rust 泛型式样 | [5]() | |--------------------------------------|---------------------------------------|---------| | List<T> Where T : IComparable { ... } | struct MyList<T: Ord> { ... } | Rust 泛型约束通过 : 直接标注在类型旁,更简洁。 | | 运行时泛型类型信息 (RTTI) | 编译期单态化 (无运行时类型信息默认) | Rust 泛型通过单态化生成具体类型代码,C# 依赖运行时类型信息。 |

四、语法风格与代码组织


维度C#Rust
代码文件结构按命名空间和类组织,需显式 using 导入按模块 (mod) 组织,通过 use 导入路径,支持嵌套模块。
注释// 单行 /* 多行 */ /// XML 文档注释// 单行 /* 多行 */ /// 文档注释 (生成 rustdoc)
分号规则语句必须以分号结尾表达式末尾分号可选(无分号则作为返回值)

总结:核心差异一览

  1. 内存安全:Rust 通过所有权/借用系统在编译期确保安全,C# 依赖 GC 运行时管理 1
  2. 类型系统:Rust 更严格(显式类型标注、无 null),C# 更灵活(隐式推断、类继承)5
  3. 代码组织:Rust 无类约束,支持全局函数和模块;C# 严格依赖类和命名空间 5
  4. 错误处理:Rust 显式 Result 类型,C# 隐式异常机制 1

建议从 变量声明、函数定义、错误处理 三个基础点开始实践,逐步过渡到所有权和 trait 系统,可显著降低学习曲线。