Rust 生锈,你是静电的!带有后处理字符串的宏?

Rust 生锈,你是静电的!带有后处理字符串的宏?,rust,lifetime,Rust,Lifetime,我试图使用递归公共表表达式(大约有80行SELECT语句)集成一个相当复杂的SQL查询。有两种不同的查询可以作为递归的种子。我不希望在代码中嵌入两个不同的80行SQL语句,但我也希望避免每次使用时都重新计算这些表达式,所以lazy\u static与一起包含似乎是一条路要走 lazy_static! { static ref select_kasten_by_title_sql: &'static str = str::replace( include_str!(

我试图使用递归公共表表达式(大约有80行SELECT语句)集成一个相当复杂的SQL查询。有两种不同的查询可以作为递归的种子。我不希望在代码中嵌入两个不同的80行SQL语句,但我也希望避免每次使用时都重新计算这些表达式,所以
lazy\u static
一起包含似乎是一条路要走

lazy_static! {
    static ref select_kasten_by_title_sql: &'static str = str::replace(
        include_str!("sql/select_kasten_by_parameter.sql"),
        "QUERYPARAMETER",
        "zettlen.title"
    )
    .as_str();
}
除了我不断得到:

5 | static ref select_kasten_by_title_sql:&'static str=str::replace(
|   ___________________________________________________________^
|  |___________________________________________________________|
| ||
26 | | | include_str!(“sql/select_kasten_by_parameter.sql”),
27 | | | |“查询参数”,
28 | | | |“zettlen.title”)。as|u str();
|| | | | uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu-uuuuuuuuuuuuuuuuuuuuuu^返回一个引用当前函数拥有的数据的值
| |_________________________|
|此处创建的临时值

这让我很困惑,因为我无法确定它指的是什么函数。我知道有一个临时值,但它的生存期应该是这个表达式的持续时间,不是吗?一旦它被设置为静态str,就是这样,对吗?

replace
创建一个新的拥有的
字符串,它的生存期应该与周围的作用域一样长,因此
as\u str
返回的切片具有该生存期。但是您随后试图将其分配给一个
&'static str
变量

您可以通过将静态变量的类型改为
String
来修复它

lazy_static! {
    static ref select_kasten_by_title_sql: String = str::replace(
        include_str!("sql/select_kasten_by_parameter.sql"),
        "QUERYPARAMETER",
        "zettlen.title"
    );
}

replace
创建一个新的拥有的
字符串
,该字符串的有效期与周围作用域的有效期一样长,因此
as_str
返回的切片具有该有效期。但是您随后试图将其分配给一个
&'static str
变量

您可以通过将静态变量的类型改为
String
来修复它

lazy_static! {
    static ref select_kasten_by_title_sql: String = str::replace(
        include_str!("sql/select_kasten_by_parameter.sql"),
        "QUERYPARAMETER",
        "zettlen.title"
    );
}

拆分变量可以更容易地可视化:

lazy\u static!{
静态引用按标题选择\u kasten\u sql:&'static str={
让tmp=str::replace(
包括_str!(“sql/select_kasten_by_parameter.sql”),
“查询参数”,
“zettlen.头衔”,
);
tmp.as_str()
};
}
tmp
是块范围所拥有的局部变量。您正在尝试返回对
tmp
的引用-您正在尝试返回一个引用当前作用域拥有的数据的值。这是不可能的,因为编译器会告诉您:

错误[E0515]:无法返回引用局部变量'tmp'的值`
-->src/main.rs:11:5
|
11 | tmp.as|u str()
|     ---^^^^^^^^^
|     |
|返回引用当前函数拥有的数据的值
|“tmp”是在这里借来的
一个简单的修复方法是直接返回
字符串,而不是引用它:

lazy\u static!{
静态引用选择\u kasten\u by\u title\u sql:String=str::replace(
包括_str!(“sql/select_kasten_by_parameter.sql”),
“查询参数”,
“泽特伦,头衔”
);
}
如果您确实想返回一个
&'static str
,可以使用
Box::leak
。我不建议您这样做,因为它与
字符串相比没有任何好处,但它是一种选择:

lazy\u static!{
静态引用T:&'static str={
让tmp=str::replace(
包括_str!(“sql/select_kasten_by_parameter.sql”),
“查询参数”,
“zettlen.头衔”,
);
Box::leak(tmp.into_boxed_str())
};
}
``

拆分变量可以更容易地可视化:

lazy\u static!{
静态引用按标题选择\u kasten\u sql:&'static str={
让tmp=str::replace(
包括_str!(“sql/select_kasten_by_parameter.sql”),
“查询参数”,
“zettlen.头衔”,
);
tmp.as_str()
};
}
tmp
是块范围所拥有的局部变量。您正在尝试返回对
tmp
的引用-您正在尝试返回一个引用当前作用域拥有的数据的值。这是不可能的,因为编译器会告诉您:

错误[E0515]:无法返回引用局部变量'tmp'的值`
-->src/main.rs:11:5
|
11 | tmp.as|u str()
|     ---^^^^^^^^^
|     |
|返回引用当前函数拥有的数据的值
|“tmp”是在这里借来的
一个简单的修复方法是直接返回
字符串,而不是引用它:

lazy\u static!{
静态引用选择\u kasten\u by\u title\u sql:String=str::replace(
包括_str!(“sql/select_kasten_by_parameter.sql”),
“查询参数”,
“泽特伦,头衔”
);
}
如果您确实想返回一个
&'static str
,可以使用
Box::leak
。我不建议您这样做,因为它与
字符串相比没有任何好处,但它是一种选择:

lazy\u static!{
静态引用T:&'static str={
让tmp=str::replace(
包括_str!(“sql/select_kasten_by_parameter.sql”),
“查询参数”,
“zettlen.头衔”,
);
Box::leak(tmp.into_boxed_str())
};
}
``

根据
lazy\u static
的文档,初始化表达式在第一次取消引用static时运行。因此,所引用的函数是的一个实现。根据
lazy\u static
的文档,初始化表达式在第一次取消引用static时运行。因此,所引用的函数是的一个实现。