You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何不使用宏复用get_node与get_node_mut的重复代码?

不用宏消除Rust中可变/不可变函数重复代码的方案

当然可以不用宏,核心思路是通过泛型 trait 抽象可变与不可变引用的访问逻辑,将重复的导航逻辑提取到泛型函数中,让两个公开函数分别调用这个泛型函数即可。

具体实现步骤:

  1. 定义一个 trait,抽象节点左右子树的获取方式,分别为不可变引用和可变引用实现该 trait:
use std::ops::{Deref, DerefMut};

// 抽象节点子树的访问逻辑
trait NodeAccessor<'a, Key, Item: GetKey<Key>> {
    type NodeRef;

    // 获取左子节点
    fn left(self) -> Self::NodeRef;
    // 获取右子节点
    fn right(self) -> Self::NodeRef;
}

// 为不可变引用实现访问逻辑
impl<'a, Key, Item: GetKey<Key>> NodeAccessor<'a, Key, Item> for &'a Node<Key, Item> {
    type NodeRef = &'a Node<Key, Item>;

    fn left(self) -> Self::NodeRef {
        self.left.as_ref().unwrap().deref()
    }

    fn right(self) -> Self::NodeRef {
        self.right.as_ref().unwrap().deref()
    }
}

// 为可变引用实现访问逻辑
impl<'a, Key, Item: GetKey<Key>> NodeAccessor<'a, Key, Item> for &'a mut Node<Key, Item> {
    type NodeRef = &'a mut Node<Key, Item>;

    fn left(self) -> Self::NodeRef {
        self.left.as_mut().unwrap().deref_mut()
    }

    fn right(self) -> Self::NodeRef {
        self.right.as_mut().unwrap().deref_mut()
    }
}
  1. 提取泛型的导航逻辑函数,利用 trait 约束处理两种引用类型:
impl<Key, Item: GetKey<Key>, const K: usize> Bucket<Key, Item, K> {
    // 通用导航逻辑,接受实现了NodeAccessor的引用类型
    fn navigate_node<'a, T>(mut node: T, key: &Key) -> (T, usize)
    where
        T: NodeAccessor<'a, Key, Item> + Deref<Target = Node<Key, Item>>,
    {
        let mut bit_index = 0;
        while node.items.is_none() {
            node = match key.has_bit_at(bit_index) {
                false => node.left(),
                true => node.right(),
            };
            bit_index += 1;
        }
        (node, bit_index)
    }

    // 不可变版本,调用通用函数
    pub fn get_node(&self, key: &Key) -> (&Node<Key, Item>, usize) {
        self.navigate_node(self.root.as_ref(), key)
    }

    // 可变版本,调用通用函数
    pub fn get_node_mut(&mut self, key: &Key) -> (&mut Node<Key, Item>, usize) {
        self.navigate_node(self.root.as_mut(), key)
    }
}

方案说明:

  • 泛型函数navigate_node包含了所有重复的导航逻辑,通过trait NodeAccessor的约束,兼容不可变和可变两种引用类型。
  • 两个公开函数get_node和get_node_mut只需要传入对应的初始引用(as_ref/as_mut),调用通用函数即可,完全消除重复代码。
  • 这种方式比宏更清晰,类型安全,且易于维护和扩展。

内容的提问来源于stack exchange,提问作者max-lt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:50:14