第六篇: Rust 中的"静态方法"(关联函数)

Rust 中的"静态方法"(关联函数)

简单回答

是的,Rust 有静态方法,叫做"关联函数"(Associated Functions)

  • 其他语言叫:static method(静态方法)
  • Rust 叫:associated function(关联函数)
  • 本质:没有 self 参数的函数

快速对比

Java 静态方法

typescript 复制代码
class User {
    private String name;
    
    // 静态方法
    public static User create(String name) {
        return new User(name);
    }
    
    // 实例方法
    public void greet() {
        System.out.println("Hello, " + name);
    }
}

// 调用
User user = User.create("Alice");  // 静态方法
user.greet();                       // 实例方法

Rust 关联函数

rust 复制代码
struct User {
    name: String,
}

impl User {
    // 关联函数(= 静态方法)
    pub fn create(name: String) -> Self {
        Self { name }
    }
    
    // 实例方法
    pub fn greet(&self) {
        println!("Hello, {}", self.name);
    }
}

// 调用
let user = User::create(String::from("Alice"));  // 关联函数
user.greet();                                     // 实例方法

关键区别

特征 关联函数(静态方法) 实例方法
self 参数 ❌ 没有 ✅ 有(&self&mut selfself
调用方式 类型名::函数名() 实例.方法名()
需要实例 ❌ 不需要 ✅ 需要
典型用途 构造器、工厂方法、工具函数 操作实例数据

详细示例

1. 构造器模式(最常见用法)

rust 复制代码
struct User {
    id: u64,
    username: String,
    email: String,
}

impl User {
    // 标准构造器
    pub fn new(username: String, email: String) -> Self {
        Self {
            id: 0,
            username,
            email,
        }
    }
    
    // 带 ID 的构造器
    pub fn with_id(id: u64, username: String, email: String) -> Self {
        Self {
            id,
            username,
            email,
        }
    }
    
    // 默认构造器
    pub fn default() -> Self {
        Self {
            id: 0,
            username: String::from("guest"),
            email: String::from("guest@example.com"),
        }
    }
}

fn main() {
    // 调用不同的关联函数(构造器)
    let user1 = User::new(
        String::from("alice"),
        String::from("alice@example.com")
    );
    
    let user2 = User::with_id(
        1,
        String::from("bob"),
        String::from("bob@example.com")
    );
    
    let user3 = User::default();
}

2. 工厂方法模式

rust 复制代码
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // 标准构造器
    pub fn new(width: u32, height: u32) -> Self {
        Self { width, height }
    }
    
    // 工厂方法:创建正方形
    pub fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
    
    // 工厂方法:从数组创建
    pub fn from_array(arr: [u32; 2]) -> Self {
        Self {
            width: arr[0],
            height: arr[1],
        }
    }
}

fn main() {
    let rect = Rectangle::new(10, 20);
    let square = Rectangle::square(15);
    let from_arr = Rectangle::from_array([30, 40]);
}

3. 工具函数(不需要实例的功能)

rust 复制代码
struct MathUtils;

impl MathUtils {
    // 关联函数:计算最大公约数
    pub fn gcd(a: i32, b: i32) -> i32 {
        if b == 0 {
            a
        } else {
            Self::gcd(b, a % b)
        }
    }
    
    // 关联函数:判断素数
    pub fn is_prime(n: i32) -> bool {
        if n <= 1 {
            return false;
        }
        for i in 2..=(n as f64).sqrt() as i32 {
            if n % i == 0 {
                return false;
            }
        }
        true
    }
    
    // 关联函数:阶乘
    pub fn factorial(n: u32) -> u64 {
        match n {
            0 | 1 => 1,
            _ => n as u64 * Self::factorial(n - 1),
        }
    }
}

fn main() {
    println!("GCD(48, 18) = {}", MathUtils::gcd(48, 18));
    println!("7 是素数吗? {}", MathUtils::is_prime(7));
    println!("5! = {}", MathUtils::factorial(5));
}

4. 建造者模式(Builder Pattern)

rust 复制代码
#[derive(Debug)]
struct User {
    username: String,
    email: String,
    age: Option<u32>,
    bio: Option<String>,
}

struct UserBuilder {
    username: String,
    email: String,
    age: Option<u32>,
    bio: Option<String>,
}

impl UserBuilder {
    // 关联函数:创建 Builder
    pub fn new(username: String, email: String) -> Self {
        Self {
            username,
            email,
            age: None,
            bio: None,
        }
    }
    
    // 实例方法:设置年龄
    pub fn age(mut self, age: u32) -> Self {
        self.age = Some(age);
        self
    }
    
    // 实例方法:设置简介
    pub fn bio(mut self, bio: String) -> Self {
        self.bio = Some(bio);
        self
    }
    
    // 实例方法:构建最终对象
    pub fn build(self) -> User {
        User {
            username: self.username,
            email: self.email,
            age: self.age,
            bio: self.bio,
        }
    }
}

fn main() {
    // 链式调用
    let user = UserBuilder::new(
        String::from("alice"),
        String::from("alice@example.com")
    )
    .age(25)
    .bio(String::from("Rust 开发者"))
    .build();
    
    println!("{:?}", user);
}

本项目中的实际应用

示例 1:UserService(src/services/user_service.rs)

rust 复制代码
pub struct UserService {
    db: MySqlPool,
    cache: RedisCache,
}

impl UserService {
    /// 关联函数(构造器)
    /// 创建新的 UserService 实例
    pub fn new(db: MySqlPool, cache: RedisCache) -> Self {
        Self { db, cache }
    }

    /// 实例方法
    /// 创建用户
    pub async fn create_user(&self, payload: CreateUserRequest) -> Result<User> {
        // 业务逻辑...
    }

    /// 实例方法
    /// 获取用户
    pub async fn get_user(&self, user_id: i64) -> Result<Option<User>> {
        // 业务逻辑...
    }
}

使用方式

ini 复制代码
// 关联函数:创建服务实例
let service = UserService::new(pool, cache);

// 实例方法:使用服务
let user = service.create_user(req).await?;
let found = service.get_user(1).await?;

示例 2:RedisCache(src/utils/cache.rs)

rust 复制代码
pub struct RedisCache {
    client: ConnectionManager,
}

impl RedisCache {
    /// 关联函数(异步构造器)
    pub async fn new(redis_url: &str) -> RedisResult<Self> {
        let client = redis::Client::open(redis_url)?;
        let connection_manager = ConnectionManager::new(client).await?;
        Ok(RedisCache {
            client: connection_manager,
        })
    }

    /// 实例方法
    pub async fn get(&self, key: &str) -> RedisResult<Option<String>> {
        let mut conn = self.client.clone();
        conn.get(key).await
    }

    /// 实例方法
    pub async fn set(&self, key: &str, value: &str, ttl: usize) -> RedisResult<()> {
        let mut conn = self.client.clone();
        conn.set_ex(key, value, ttl).await
    }
}

使用方式

csharp 复制代码
// 关联函数:创建缓存实例
let cache = RedisCache::new("redis://localhost:6379").await?;

// 实例方法:使用缓存
cache.set("key", "value", 3600).await?;
let value = cache.get("key").await?;

示例 3:gRPC 服务实现(src/grpc/service.rs)

rust 复制代码
pub struct UserServiceImpl {
    pool: MySqlPool,
    cache: Arc<RedisCache>,
}

impl UserServiceImpl {
    /// 关联函数(构造器)
    pub fn new(pool: MySqlPool, cache: Arc<RedisCache>) -> Self {
        Self { pool, cache }
    }
}

#[tonic::async_trait]
impl UserService for UserServiceImpl {
    /// 实例方法(gRPC 接口实现)
    async fn create_user(
        &self,
        request: Request<CreateUserRequest>,
    ) -> Result<Response<CreateUserResponse>, Status> {
        // 实现逻辑...
    }
}

使用方式

css 复制代码
// 关联函数:创建 gRPC 服务实例
let user_service = UserServiceImpl::new(pool.clone(), cache.clone());

// 注册到 gRPC 服务器
Server::builder()
    .add_service(UserServiceServer::new(user_service))
    .serve(addr)
    .await?;

常见模式总结

1. 命名约定

函数名 用途 示例
new() 标准构造器 User::new(name, email)
default() 默认值构造器 User::default()
with_*() 带特定参数的构造器 User::with_id(1, name)
from_*() 类型转换构造器 User::from_string(json)
builder() 建造者模式入口 User::builder()

2. 调用语法

php 复制代码
// 关联函数使用 :: 调用
User::new(name, email)
String::from("hello")
Vec::with_capacity(10)

// 实例方法使用 . 调用
user.get_name()
string.len()
vec.push(1)

3. self 参数类型

php 复制代码
impl MyStruct {
    // 关联函数(无 self)
    fn new() -> Self { }
    
    // 不可变借用
    fn read_data(&self) { }
    
    // 可变借用
    fn modify_data(&mut self) { }
    
    // 获取所有权(消费 self)
    fn consume(self) { }
}

与其他语言对比

Python

ruby 复制代码
class User:
    def __init__(self, name):  # 实例方法
        self.name = name
    
    @staticmethod              # 静态方法
    def create(name):
        return User(name)
    
    @classmethod               # 类方法
    def from_dict(cls, data):
        return cls(data['name'])

Java

arduino 复制代码
class User {
    private String name;
    
    public User(String name) {  // 构造器
        this.name = name;
    }
    
    public static User create(String name) {  // 静态方法
        return new User(name);
    }
}

Rust

rust 复制代码
struct User {
    name: String,
}

impl User {
    pub fn new(name: String) -> Self {  // 关联函数
        Self { name }
    }
    
    pub fn create(name: String) -> Self {  // 关联函数
        Self { name }
    }
}

为什么叫"关联函数"?

因为这些函数关联(associated) 到特定类型,但不需要该类型的实例。

rust 复制代码
impl String {
    // 关联到 String 类型
    pub fn from(s: &str) -> String { }
}

impl Vec<T> {
    // 关联到 Vec<T> 类型
    pub fn new() -> Self { }
    pub fn with_capacity(capacity: usize) -> Self { }
}

总结

问题 答案
Rust 有静态方法吗? ✅ 有,叫关联函数
如何定义? impl 块中没有 self 参数的函数
如何调用? 类型名::函数名()
常见用途? 构造器、工厂方法、工具函数
关键字? ❌ 没有 static 关键字,只是普通函数

记忆要点

  • self = 实例方法(需要实例调用)
  • self = 关联函数(类型名调用)
  • :: = 关联函数调用符号
  • . = 实例方法调用符号

延伸阅读

相关推荐
勤奋的小小尘1 小时前
第七篇: Rust 多线程与并发编程详解
rust
猛喝威士忌1 小时前
Tauri 和 enigo 你们不许再崩溃啦!
rust·客户端
q***31893 小时前
数据库操作与数据管理——Rust 与 SQLite 的集成
数据库·rust·sqlite
百锦再14 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
芳草萋萋鹦鹉洲哦14 小时前
【Windows】tauri+rust运行打包工具链安装
开发语言·windows·rust
s91236010117 小时前
【Rust】m2 mac 编译linux 、aarch、win 程序
rust
Source.Liu17 小时前
【ISO8601库】日期时间解析器测试套件详解(tests.rs)
rust·time·iso8601
alwaysrun18 小时前
Rust中数组简介
rust·数组·array·切片
百锦再18 小时前
第12章 测试编写
android·java·开发语言·python·rust·go·erlang