我目前正在尝试在Rust中编写一个小命令行应用程序,并且我已经终生难忘.
extern crate clap;
use self::clap::{App, Arg};
use std::env;
impl<'p> Params<'p> {
fn get_username_arg<'r>() -> Arg<'r, 'r> {
let mut arg = Arg::with_name("Username")
.short("u")
.long("username")
.takes_value(true);
match env::var("USERNAME") {
Ok(username) => {
// How do I pass `username` to default_value?
arg.default_value(username)
}
Err(e) => arg.required(true),
}
}
// More code below...
}
Run Code Online (Sandbox Code Playgroud)
问题是我正在尝试传递username默认值方法,该方法需要str具有生命周期的方法'r.我尝试克隆,但我无法弄清楚如何告诉它克隆的生命周期是什么.我尝试了以下几点:
let cln = (&*username).clone::<'r>();
arg.default_value(username)
Run Code Online (Sandbox Code Playgroud)
出于某种原因,它现在告诉我,username活得不够长,即使自从克隆数据以来它也无关紧要.
所以我的问题是,如何进行编译?
编辑:我想补充一点,对我来说重要的是签名与生命周期参数保持一致.我不介意做一些昂贵的操作,比如克隆来完成这项工作.
我正在通过官方书籍学习 Rust。我在程序中遇到了奇怪的语法:
pub struct Shelf<'a> {
items: Vec<&'a Item<'a>>, // => working as expected
//items: Vec<Item<'a>>, // => not working
//items: Vec<&'a Item>, // => not working
}
Run Code Online (Sandbox Code Playgroud)
Item 是一个结构体,也包含对其他类型的引用:
pub struct Item<'a> {
owner: &'a Owner,
name: String,
avg_rating: u32,
status: ItemStatus,
}
pub struct Owner {
pub name: String,
}
Run Code Online (Sandbox Code Playgroud)
在我看来,语法items: Vec<&'a Item<'a>>很奇怪,我认为我做得不对...我想要的是Vec包含对Items 的引用的 a ,Vec只要Item它包含的对 s 的引用本身有效,它就是有效的。不应该是items: Vec<&'a Item>这样吗?
我正在阅读 Rust Book,所有内容都很容易理解(感谢这本书的作者),直到关于生命周期的部分。我花了一整天,阅读了很多关于生命的文章,但我仍然对正确使用它们感到非常不安。
不过,我确实理解的是,显式生命周期说明符的概念旨在解决悬空引用的问题。我也知道 Rust 有引用计数智能指针 ( Rc),我相信它与shared_ptrC++ 中的相同,具有相同的目的:防止悬空引用。
鉴于这些生命周期对我来说是如此可怕,而且智能指针对我来说非常熟悉和舒适(我在 C++ 中经常使用它们),我可以避免使用智能指针的生命周期吗?还是生命周期是我必须在 Rust 代码中理解和使用的不可避免的事情?
给VisualRust另一个尝试,看看他们有多远,我写了几行代码.像往常一样,代码使我在stackoverflow上写一个问题......
首先,请稍后阅读我的问题:
fn make_counter( state : &mut u32 ) -> Box<Fn()->u32>
{
Box::new(move || {let ret = *state; *state = *state + 1; ret })
}
fn test_make_counter() {
let mut cnt : u32 = 0;
{
let counter = make_counter( & mut cnt );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
}
fn alt_make_counter ( init : u32 ) -> Box<Fn()->u32> {
let mut state = init;
Box::new(move || {let ret …Run Code Online (Sandbox Code Playgroud) 当您创建一个以多个引用作为输入的函数,并返回一个引用作为输出时,您需要指定输出引用的生命周期与哪个或多个输入引用相关联。这是有道理的。
没有意义的事情是为什么您需要定义多个通用生命周期。你只能有一个返回值。
在这里,我们定义了'a和'b- 两个通用生命周期。在返回值上,我们可以指定'a或'b- 不能同时指定:
fn foo<'a, 'b>(ref1: &'a str, ref2: &'b str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
这似乎可以缩短为:
fn foo<'a>(ref1: &'a str, ref2: &str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
如果我们想将输出的生命周期与第二个输入参数联系起来,我们可以这样做:
fn foo<'a>(ref1: &str, ref2: &'a str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
如果我们想将它与两者联系起来,我们可以这样做:
fn foo<'a>(ref1: &'a str, ref2: &'a str) -> &'a str {}
Run Code Online (Sandbox Code Playgroud)
这涵盖了所有场景(至少在这个简单示例中),并且这些场景都不需要定义一个以上的通用生命周期(定义'b)。
是否有过需要定义多个通用生命周期的情况?
我想写一个小型阶乘库。请查看库主模块内的代码:
pub fn results() -> const [i8; 6] { [
1,
1,
2,
6,
24,
120,
//720 is too large for i8.
] }
pub fn results() -> const [i32; 13] { [
1,
1,
2,
6,
24,
120,
720,
5_040,
40_320,
362_880,
3_628_800,
39_916_800,
479_001_600,
//6_227_020_800 is too large for i32.
] }
Run Code Online (Sandbox Code Playgroud)
对于第一个函数的返回类型,它给了我这个错误:
pub fn results() -> const [i8; 6] { [
1,
1,
2,
6,
24,
120,
//720 is too large for i8.
] }
pub fn …Run Code Online (Sandbox Code Playgroud) 为什么借用检查器会对下面代码中的生命周期感到困惑
fn main() {
let ss = "abc"; // lets say 'a scope
let tt = "def"; // lets say 'b scope
let result = func(ss, tt);
}
fn func(s: &str, t: &str) -> &str {
t
}
Run Code Online (Sandbox Code Playgroud)
| fn func(s: &str, t: &str) -> &str {
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `s` or `t`
Run Code Online (Sandbox Code Playgroud)
为什么这个代码会发生什么?我错过了一些非常重要的边缘案例吗?
但是当我用生命时间标签对它们进行注释时,它可以工作.
fn …Run Code Online (Sandbox Code Playgroud)