惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Y
Y Combinator Blog
T
Tailwind CSS Blog
G
Google Developers Blog
博客园 - Franky
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 聂微东
爱范儿
爱范儿
博客园 - 【当耐特】
腾讯CDC
T
The Blog of Author Tim Ferriss
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
C
Check Point Blog
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

The Rust Programming Language Forum - Latest topics

Beginner building a Rust backend framework (AI-assisted) — feedback appreciated C++ to Rust -- Exceptions Re-exporting a trait with a custom derive_macro Gold linker is deprecated Why is using PhantomData valid in this case? Code review for Static Pool Allocator Looking for a pool based allocator Why is this legal? What does it mean for Rustc to run "out of TLS keys"? Using async/await internally with no internal runtime, but exposing a nonblocking poll API — is this a reasonable design? Testing functions that use randomness `cargo-path`: improve coding agents&#39; ability to find Rust documentation Rust task runners Lifetime weird case Windows - USB device not detected A random rustc-ice-[...].txt file appeared Develop rust where the environment is setup in a docker Undefined Behavior: in-bounds pointer arithmetic failed: attempting to offset pointer by 20 bytes, but got alloc238 which is only 1 byte from the end of the allocation Unbug 0.5 - Runtime debug assertions Is there a tiny error in section 6.2 Reference types? Lifetime woes implementing ratatui::Widget for a reference Rusqlite + Chrono: How do I simplify code to obtain chrono datetime value From OOP to Rust – struggling with code organization and data structure design Way to avoid a self-referential struct Rust RF and audio resources/communities Whyhttp - HTTP mocks that fail where the bug actually is Using tokio channel permits in a tower service Arc::increment_strong_count design question (cross-post) `&T`, `&mut T`, `Pin<&mut T>` and `&Cell<T>`: Ways of Borrowing a `T` Ratatui detect arrow key press and release
How to call struct method as function pointer in loop
magast · 2026-04-20 · via The Rust Programming Language Forum - Latest topics

1

I write a parser to analyze the text. I want to store the methods into a HashMap, like the table-driven approach in C languange, to reduce the match-select code. then I can call the method by accessing the HashMap using the state as key. But there are a few tricky problems.
My intention is to use a concise method to replace numerous branches(match-select, if-else and so on).
NOTE: It needs to support the lifetime if feasible.

The sample code as following:

use std::collections::HashMap;

//It needs to set lifetime to match the Parser<'a>
type HandlerPtr<'a> = fn(&'a mut Parser<'a>)->i32;

//It need lifetime to support the buffer reference
pub struct Parser<'a> {
    //It MUST be the reference here
    buffer: &'a [u8],
    state: i32,
    handlers: HashMap<i32, HandlerPtr<'a>>,
}

impl<'a> Parser<'a> {
    pub fn new(buf: &'a [u8]) -> Self {
        Self{
            buffer: buf,
            state: -1,
            handlers: HashMap::new(),
        }
    }

    pub fn init(&mut self) {
        self.handlers.insert(-1, Parser::handle_none);
        self.handlers.insert(0, Parser::handle_one);

    }

    pub fn test(&'a mut self) {
        let mut state = -1_i32;
        //Compiling error when accessing the HashMap more than once
        for _i in 0..3{
            let myfn = self.handlers.get(&state).unwrap();
            state = myfn(self);
            println!("---test: {}", state);
        }
    }

    pub fn handle_none(&'a mut self) -> i32 {
        let ch = self.buffer[0];
        println!("[handle_none] {:?}", ch);
        //change state

        self.state = 0;
        self.state
    }

    pub fn handle_one(&mut self) -> i32 {
        let ch = self.buffer[1];
        println!("[handle_one] {:?}", ch);

        self.state = -1;
        self.state
    }
}

fn main() {
    let buf = [0_u8;16];
    let mut p = Parser::new(&buf);
    p.init();
    p.test();
}

The compiler report the error as:

let myfn = self.handlers.get(&state).unwrap();
   |                        ------------------------- argument requires that `*self` is borrowed for `'a`
   |             state = myfn(self);
   |                          ^^^^ `*self` was mutably borrowed here in the previous iteration of the loop

There are more then once mutable borrowed if I want to access the method function pointer. I try the version without lifetime, it works. But it seems unsolvable in the lifetime version.
Does anyone know how to fix the issues? Or can give other alternative solutions?
Thank you!

2

Change all the &'a mut to &mut to get it to compile.
(Whether you should be trying to write code how you have it could be debatable, but not much to go on.)