Rust 格式的生命周期!()中的匹配表达式太短
我正在为自己的结构实现一个自定义的Rust 格式的生命周期!()中的匹配表达式太短,rust,Rust,我正在为自己的结构实现一个自定义的Display::fmt,它表示一个间隔 struct Range<T> { lower: Option<T>, upper: Option<T>, } 我已开始实现,但在匹配表达式和格式生成的字符串的生存期方面遇到了问题!()。我的实现存在的问题是,格式返回的字符串没有足够长的使用时间 fn main() { let opt = Some(1); let opt_display = mat
Display::fmt
,它表示一个间隔
struct Range<T> {
lower: Option<T>,
upper: Option<T>,
}
我已开始实现,但在匹配
表达式和格式生成的字符串的生存期方面遇到了问题!()
。我的实现存在的问题是,格式返回的字符串没有足够长的使用时间
fn main() {
let opt = Some(1);
let opt_display = match opt {
Some(x) => &format!("{}", x), // error: borrowed value does not live long enough
None => "",
};
println!("opt: {}", opt_display);
}
为什么我的方法不起作用?什么是解决我问题的好方法?我不是生命周期方面的专家,但我相信这里的问题是,您试图从
格式创建的字符串中返回&String
代码>在匹配中。由于格式的范围仅在范围内,借阅检查器会投诉
要解决此问题,可以使用一个自有字符串
fn main() {
let opt = Some(1);
let opt_display = match opt {
Some(ref x) => format!("{}", x), // Allowed since opt_display now owns the string
None => "".into(),
};
// Another way to achieve the same thing.
//let opt_display = opt.map(|s| format!("{}", s)).unwrap_or("".into());
println!("opt: {}", opt_display);
}
因为,您正试图返回对某个值的引用,该值将在引用仍然存在时被删除。祝贺你,你只是试图创建内存不安全,这可能导致C或C++中的崩溃(或者更糟),但是锈阻止了它。p>
您可以提高效率的一个方法是仅在一种情况下分配:
fn main() {
let opt = Some(1);
let opt_display = opt.map(|s| format!("{}", s));
// Type not needed, only used to assert the type is what we expect
let opt_display_str: &str = opt_display.as_ref().map(String::as_str).unwrap_or("");
println!("opt: {}", opt_display_str);
}
您还可以使用,它允许拥有或借用字符串。注意它与另一个答案有多相似,但在None
的情况下不分配:
use std::borrow::Cow;
fn main() {
let opt = Some(1);
let opt_display: Cow<str> = match opt {
Some(ref x) => format!("{}", x).into(),
None => "".into(),
};
println!("opt: {}", opt_display);
}
替换write!(f,
用于打印!(
在格式化程序中,并在出错时返回。在实现显示时,无需返回字符串;您只需将!()
写入提供的格式化程序即可
它看起来像:
impl<T: Display> Display for Range<T> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
write!(fmt, "<")?;
if let Some(v) = self.lower {
write!(fmt, "{}", v)?;
}
write!(fmt, ",")?;
if let Some(v) = self.upper {
write!(fmt, "{}", v)?;
}
write!(fmt, ">")
}
}
impl范围显示{
fn fmt(&self,fmt:&mut格式化程序)->结果{
写!(fmt,“”)
}
}
if let Some(ref x)=
解决方案正是我想要的。我现在明白了为什么我以前的代码不起作用了。在Rust中工作肯定会让人大开眼界。感谢您的详细介绍。在进行多个编写时!(
按顺序,每个似乎都返回某种结果。编译器显示警告:必须使用未使用的结果,
。我当前使用#[允许(未使用的#必须使用)]忽略该警告
。有没有办法写入!
在fmt::Formatter
上可能会失败?这是一种不好的做法吗?@antenen是的,并且?使用结果
,就像生锈的其他地方一样,可能是“出错时返回”,就像我提到的那样。也许重新使用Rust编程语言会有所帮助?另请参见。@Antenen有没有办法在fmt::Formatter
上写入!
可能会失败?-当然。磁盘可能已满,文件可能已关闭,网络可能已断开…等等。这是一种不好的做法吗?忽略错误?绝对正确这是个坏主意,这就是为什么编译器告诉您应该使用结果的原因。我还没有阅读错误处理一章。我昨天通过阅读“这本书”开始学习生锈.非常有趣的语言。我将研究它!感谢您提供的精彩答案。我选择接受Shepmaster的答案,因为它描述了我的解决方案为什么不能最好地工作,并为我的问题提供了多种解决方案。
fn main() {
let opt = Some(1);
print!("opt: ");
if let Some(ref x) = opt {
print!("{}", x);
}
println!("");
}
impl<T: Display> Display for Range<T> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
write!(fmt, "<")?;
if let Some(v) = self.lower {
write!(fmt, "{}", v)?;
}
write!(fmt, ",")?;
if let Some(v) = self.upper {
write!(fmt, "{}", v)?;
}
write!(fmt, ">")
}
}