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

Rust中使用Tiberius查询MS SQL返回Vec的生命周期借用错误

解决Tiberius读取SQL数据返回Vec<结构体>的借用错误

错误原因

错误提示cannot return value referencing local variable 'row'的核心问题是:Fornitori结构体中的&str字段引用的是函数内局部变量row中Row对象的数据。函数执行完毕后row会被销毁,对应的引用会变成悬垂引用,Rust的所有权机制会直接阻断这种不安全操作。

解决方案

将结构体中的引用类型替换为拥有所有权的String类型,让结构体持有自己的数据,不再依赖局部变量的生命周期。

修改后的结构体定义

#[derive(Clone, Debug)]
pub struct Fornitori {
    pub f_id: Option<i32>,
    pub fornitore: Option<String>,
    pub tipo_pagamento: Option<String>,
}

修改后的函数代码

use tiberius::{Client, Config, AuthMethod, Query, Row};
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncWriteCompatExt;
pub mod structures;
use structures::*;

#[tokio::main]
pub async fn get_fornitori() -> anyhow::Result<Vec<Fornitori>> {
    let mut config = Config::new();

    config.host("foo");
    config.port(1433);
    config.authentication(AuthMethod::sql_server("foo", "bar"));
    config.database("foo");
    config.trust_cert(); // 生产环境不建议这么做

    let tcp = TcpStream::connect(config.get_addr()).await?;
    tcp.set_nodelay(true)?;

    let mut client = Client::connect(config, tcp.compat_write()).await?;
    let params = vec![String::from("*")];
    let mut select = Query::new("SELECT TOP 3 * FROM foo");
    
    for param in params.into_iter() {
        select.bind(param);
    }
    
    let mut _res = select.query(&mut client).await?;
    let row: Vec<Vec<Row>> = _res.into_results().await?;

    let mut result_vec: Vec<Fornitori> = vec![];
    for i in &row[0] {
        let id_forn: Option<i32> = i.get(0);
        // 将查询得到的&str转换为String,通过map处理Option类型
        let nome_forn: Option<String> = i.get::<&str>(1).map(|s| s.to_string());
        let pagamento_forn: Option<String> = i.get::<&str>(4).map(|s| s.to_string());
        let forn = Fornitori {
            f_id: id_forn,
            fornitore: nome_forn,
            tipo_pagamento: pagamento_forn,
        };
        result_vec.push(forn);
    }
    println!("rvec: {:#?}", result_vec);

    Ok(result_vec)
}

说明

修改后,结构体Fornitori拥有自己的字符串数据,不再依赖函数内局部变量的生命周期,函数返回时就不会触发借用检查错误。

内容的提问来源于stack exchange,提问作者GranBoh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:20:20