MST

星途 面试题库

面试题:Rust结构体在异步编程中的方法实现与生命周期管理

定义一个结构体`DatabaseConnection`,用于管理数据库连接。结构体内部有必要的字段来保存连接状态等信息。实现一个异步方法`query`,该方法接受一个SQL查询语句作为参数,返回查询结果。由于数据库连接可能有不同的生命周期,需要妥善处理异步操作中的生命周期问题,确保在异步执行过程中连接不会被提前释放。请写出完整的代码实现,包括合适的异步运行时和必要的生命周期标注。
44.3万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::sync::Arc;
use tokio::sync::Mutex;
use futures::future::BoxFuture;
use tokio_postgres::{Client, Config, NoTls};

// 定义DatabaseConnection结构体
struct DatabaseConnection {
    client: Option<Client>,
    connected: bool,
}

impl DatabaseConnection {
    // 初始化连接
    async fn new() -> Result<Self, tokio_postgres::Error> {
        let config = Config::new()
          .user("your_username")
          .password("your_password")
          .host("localhost")
          .port(5432)
          .dbname("your_database");
        let (client, connection) = config.connect(NoTls).await?;
        tokio::spawn(async move {
            if let Err(e) = connection.await {
                eprintln!("Database connection error: {}", e);
            }
        });
        Ok(Self {
            client: Some(client),
            connected: true,
        })
    }

    // 异步查询方法
    async fn query(&mut self, sql: &str) -> Result<Vec<tokio_postgres::Row>, tokio_postgres::Error> {
        if let Some(ref mut client) = self.client {
            client.query(sql, &[]).await
        } else {
            Err(tokio_postgres::Error::Db("Not connected".to_string()))
        }
    }
}

// 异步运行时
#[tokio::main]
async fn main() {
    let mut db = DatabaseConnection::new().await.expect("Failed to connect to database");
    let result = db.query("SELECT * FROM your_table").await;
    match result {
        Ok(rows) => {
            for row in rows {
                println!("{:?}", row);
            }
        },
        Err(e) => eprintln!("Query error: {}", e),
    }
}

上述代码以Rust语言为例,实现了一个管理数据库连接的结构体DatabaseConnection以及一个异步查询方法query。这里使用tokio_postgres库来处理PostgreSQL数据库连接。

  1. 结构体定义DatabaseConnection结构体包含client字段用于保存数据库客户端实例,connected字段用于标识连接状态。
  2. 初始化连接new方法负责初始化数据库连接,并将连接的生命周期通过tokio::spawn进行妥善管理,避免在异步操作中提前释放。
  3. 异步查询query方法确保在执行查询时,数据库连接是有效的,若连接存在则执行查询并返回结果。
  4. 异步运行时:使用tokio::main作为异步运行时入口,在main函数中初始化数据库连接并执行查询操作。

如果是其他语言,实现思路类似,但语法和具体库的使用会有所不同。例如在Python中可使用asyncpg库来处理异步PostgreSQL连接:

import asyncio
import asyncpg

# 定义DatabaseConnection类
class DatabaseConnection:
    def __init__(self):
        self.client = None
        self.connected = False

    # 初始化连接
    async def new(self):
        try:
            self.client = await asyncpg.connect(user='your_username', password='your_password', host='localhost', port=5432, database='your_database')
            self.connected = True
        except Exception as e:
            print(f"Failed to connect to database: {e}")

    # 异步查询方法
    async def query(self, sql):
        if self.connected and self.client:
            return await self.client.fetch(sql)
        else:
            raise Exception("Not connected")

# 异步运行时
async def main():
    db = DatabaseConnection()
    await db.new()
    try:
        result = await db.query("SELECT * FROM your_table")
        for row in result:
            print(row)
    except Exception as e:
        print(f"Query error: {e}")

if __name__ == "__main__":
    asyncio.run(main())

在Python代码中:

  1. 类定义DatabaseConnection类包含clientconnected属性。
  2. 初始化连接new方法负责建立数据库连接。
  3. 异步查询query方法在连接有效时执行查询并返回结果。
  4. 异步运行时:使用asyncio.run来运行异步main函数,在main函数中初始化连接并执行查询。