返回文章列表

文章

Rust中的?运算符

目录
  1. 下面是对 Rust、Java、Kotlin 中与 ? 运算符相关语法的系统整合与对比,涵盖其含义、用法、典型示例和语义差异,帮助你从跨语言的视角深入理解:
  2. 🔍 ? 运算符在三种语言中的角色一览
  3. 🧠 Rust 中的 ? 运算符
  4. ✅ 功能
  5. ✅ 示例
  6. 🧠 Kotlin 中的 ? 系列操作符
  7. 1. ?. 安全调用(null-safe access)
  8. 2. ?: Elvis 操作符(默认值)
  9. 3. !! 强制非 null(可能抛异常)
  10. 🧠 Java 中无 ? 运算符,但手动空值判断
  11. 手动处理 null:
  12. 或用 Optional(Java 8+):
  13. 🔁 关键用法对照表
  14. 🔎 更深层次对比(语义 & 编译器)
  15. 🧪 示例对照(解析并加上手续费)
  16. ✅ Rust
  17. ✅ Kotlin
  18. ✅ Java
  19. 📌 总结

下面是对 Rust、Java、Kotlin 中与 ? 运算符相关语法的系统整合与对比,涵盖其含义、用法、典型示例和语义差异,帮助你从跨语言的视角深入理解:#

🔍 ? 运算符在三种语言中的角色一览#

语言? 相关语法作用类别主要用于是否控制流程可否传播错误编译器强制
Rust?错误传播Result<T, E> / Option<T>✅ 是✅ 是✅ 是
Kotlin?., ?:, !!空值控制T?(nullable 类型)❌ 否❌ 否⚠️ 部分
Java? 语法(手动 null 判断)空值控制null❌ 否❌ 否❌ 否

🧠 Rust 中的 ? 运算符#

✅ 功能#

  • 用于 ResultOption 类型解包
  • 如果是 ErrNone立即返回当前函数的错误
  • 本质是简洁的错误传播机制

✅ 示例#

fn parse_number(s: &str) -> Result<i32, std::num::ParseIntError> {
    let num = s.parse::<i32>()?;  // 自动传播错误
    Ok(num + 1)
}

等价于:

let num = match s.parse::<i32>() {
    Ok(n) => n,
    Err(e) => return Err(e),
};

🧠 Kotlin 中的 ? 系列操作符#

1. ?. 安全调用(null-safe access)#

val name: String? = getUserName()
val length = name?.length  // 如果为 null,则结果是 null

2. ?: Elvis 操作符(默认值)#

val length = name?.length ?: 0  // name 为 null 时返回 0

3. !! 强制非 null(可能抛异常)#

val length = name!!.length  // 如果 name 为 null,则 NPE

🧠 Java 中无 ? 运算符,但手动空值判断#

手动处理 null:#

String name = getName();
int length = name != null ? name.length() : 0;

或用 Optional(Java 8+):#

Optional<String> name = Optional.ofNullable(getName());
int length = name.map(String::length).orElse(0);

🔁 关键用法对照表#

目标/功能RustKotlinJava
自动错误传播let x = foo()?❌ 无等价机制❌ 手动 try-catch
安全空值访问Option<T> + ?if let?. 安全访问if (x != null)
提供默认值unwrap_or(default)?: Elvis 操作符?: 三元运算符
强制解包unwrap()(不推荐)!!(不推荐)x.get()(Optional)或直接访问
语法控制流程✅(?return
需要显式处理错误✅ 强制处理 Result 类型⚠️ 可选❌ 可忽略(不推荐)

🔎 更深层次对比(语义 & 编译器)#

对比点Rust ?Kotlin ?Java Optional / null
错误 or 空值处理✅ 统一编译期错误处理✅ 空值控制但非强制处理❌ 常出现 NPE
是否强制检查✅ 编译器强制处理 Result⚠️ 编译器不强制处理 null❌ 完全靠开发者小心操作
编码风格函数式 + 显式错误传播函数式 + 语法糖空值访问面向对象 + 显式判断

🧪 示例对照(解析并加上手续费)#

✅ Rust#

fn total_cost(s: &str) -> Result<i32, std::num::ParseIntError> {
    let qty = s.parse::<i32>()?;         // 自动传播错误
    Ok(qty * 5 + 1)
}

✅ Kotlin#

fun totalCost(s: String): Int? {
    val qty = s.toIntOrNull() ?: return null
    return qty * 5 + 1
}

✅ Java#

public Integer totalCost(String s) {
    try {
        int qty = Integer.parseInt(s);
        return qty * 5 + 1;
    } catch (NumberFormatException e) {
        return null;
    }
}


📌 总结#

Rust ?Kotlin ? / ?: / !!Java
用途错误传播(Result/Option)空值控制(nullable 类型)手动判断或 Optional
主要能力解构 + 提前返回空值访问 + 默认值 + NPE 抛出明确空值或异常处理
强制性编译器强制错误处理非强制无强制,容易遗漏
表达力 & 简洁性✅ 高✅ 高⚠️ 相对繁琐