无法返回引用本地数据的值

问题描述 投票:0回答:3

我是生锈新手。下面的 get_x509 函数会创建一个编译器警告“无法返回引用本地数据的值

pem.contents
”。我想我明白为什么 - 因为返回值引用 pem.contents ,它仅在该函数的范围内 - 但我无法弄清楚如何让它工作。

下面代码中的 x509 函数来自 x509_parser crate

use x509_parser::prelude::*;

fn main() {
    let cert = "";
    get_x509(cert);
}

fn get_x509(cert: &str) -> X509Certificate {
    let res_pem = parse_x509_pem(cert.as_bytes());
    let x509_cert = match res_pem {
        Ok((_, pem)) => {
            let res_cert = parse_x509_certificate(&pem.contents);
            match res_cert {
                Ok((_, certificate)) => certificate,
                Err(_err) => {
                    panic!("Parse failed")
                }
            }
        }
        Err(_err) => {
            panic!("Parse failed")
        }
    };
    return x509_cert;
}

我尝试将 cert 变量设置为静态值。如果我在 main() 函数中内联上述代码,它就可以工作(但我必须匹配 &res_pem 而不是 res_pem)。

rust borrow-checker
3个回答
0
投票

根据x509-parser-0.14.0/src/certificate.rs

parse_x509_certificate
的参数和返回值都具有与其关联的生命周期
'a
。解决该问题的一种方法是将
get_x509
分成两个函数,并且可以以某种方式避免在调用
parse_x509_certificate
的第二个函数中进行本地引用。

以下代码可以编译(但在运行时会出现恐慌,因为

cert
为空):

fn main() {
    let cert = "";
    let pem = get_x509_pem(cert);
    get_x509(&pem); // Return value is unused.
}

use x509_parser::prelude::*;

fn get_x509_pem(cert: &str) -> Pem {
    let (_, pem) = parse_x509_pem(cert.as_bytes()).expect("Parse failed");
    pem
}

fn get_x509(pem: &Pem) -> X509Certificate {
    let x509_cert = match parse_x509_certificate(&pem.contents) {
        Ok((_, certificate)) => certificate,
        Err(_err) => {
            panic!("Parse failed")
        }
    };
    x509_cert
}

0
投票

正如您所说,这里的问题是您有一些仅存在于函数上下文中的东西,并且您想要返回对它(或它的某些部分)的引用。但是,当函数执行完成时,底层数据将被删除,因此您将返回一个悬空引用 - Rust 可以防止这种情况发生。

解决这个问题的方法是(西蒙史密斯的答案很好地说明了)返回您想要引用的数据,而不仅仅是返回引用。因此,在您的情况下,您希望返回整个

resp_pem
对象,然后进行进一步的数据提取。

阅读库的文档,您似乎处于一种不幸的情况,无法将

res_pem
从函数移到静态空间,因为
parse_x509_pem
返回拥有的数据,而
X509Certificate
包含引用。因此,返回的证书的生命周期必须比函数的生命周期长,但是您引用的对象 (
res_pem
) 由该函数拥有,并在函数执行完成时被删除。


0
投票

我也有几乎同样的问题。我试图在结构中解析 CertificateDer 并使 X509Certificate 成为结构的一部分。 它说它需要一些生命周期,但最后,我总是要么知道这个东西没有足够的生命周期,要么无法返回引用。虽然它确实具有克隆特征,但似乎数据并没有被复制保存在结构中。

pub struct X509Information<'a> {
    pub x509: Option<X509Certificate<'a>>,
    pub subject: String,
    pub attributes: std::collections::HashMap<String, String>,
}

当下一步工作时,结果无法保存在结构中:

pub fn parse_der_to_x509<'a>(
    certificate: &'a CertificateDer<'a>
) -> Result<X509Certificate<'a>, String> {
    match parse_x509_certificate(certificate) {
        Ok((_, x509)) => Ok(x509),
        Err(error) => Err(format!("error parsing certificate: {}", error))
    }
}

还有其他想法吗?

© www.soinside.com 2019 - 2024. All rights reserved.