Generics 在Rust中使用泛型类型引用时,为什么必须指定生存期?
我正在为一个Generics 在Rust中使用泛型类型引用时,为什么必须指定生存期?,generics,reference,rust,serde,Generics,Reference,Rust,Serde,我正在为一个serde_json::value::value引用实现Rust的TryFrom特性,以及一个将Vec转换为Vec的函数,其中T实现TryFrom。因为我必须在函数中为值引用指定生存期,所以我无法从返回T::try\u的结果(已删除借用值) 我尝试了另一种可行的方法;创建我自己的特性,类似于从尝试,但没有通用的。这是可行的,但我不明白为什么我不能使用TryFrom和泛型,因为这个特性已经存在了 引发编译时错误的我的通用代码: impl TryFrom<&Value>
serde_json::value::value
引用实现Rust的TryFrom
特性,以及一个将Vec
转换为Vec
的函数,其中T
实现TryFrom
。因为我必须在函数中为值
引用指定生存期,所以我无法从返回T::try\u的结果(已删除借用值)
我尝试了另一种可行的方法;创建我自己的特性,类似于从
尝试,但没有通用的。这是可行的,但我不明白为什么我不能使用TryFrom
和泛型,因为这个特性已经存在了
引发编译时错误的我的通用代码:
impl TryFrom<&Value> for Channel {
type Error = &'static str;
fn try_from(value: &Value) -> Result<Self, Self::Error> {
let title = value.get("title").ok_or("couldn't find title property in json")?
.as_str().ok_or("title was not a string")?;
let name = value.get("user_name").ok_or("couldn't find user_name property in json")?
.as_str().ok_or("user_name was not a string")?;
Ok(Channel {
title: String::from(title),
user_name: String::from(name)
})
}
}
// I must add a lifetime below. Please ignore the self reference.
fn get_many_generic<'a, T: TryFrom<&'a Value>>(&self, url_str: &str) -> Result<Vec<T>, Box<dyn std::error::Error>> {
// perform_get returns a serde_json::Value
let mut value = &self.perform_get(url_str)?;
if let Value::Object(map) = value {
value = map.get("data").ok_or("found a map without a 'data' property when expecting an array")?;
}
if let Value::Array(vec) = value {
Ok(vec.iter()
.filter_map(|item|
match T::try_from(item) {
Ok(model) => Some(model),
Err(e) => {
println!("Could not deserialize value {}", item);
None
}
}
).collect())
}
else {
Err(Box::new(
Error::new(format!("Expected array from {}, but didn't receive one.", url_str))
))
}
}
impl TryFrom用于通道{
类型错误=&'static str;
fn try_from(值:&value)->结果{
让title=value.get(“title”).ok_或(“在json中找不到title属性”)?
.as_str().ok_或(“标题不是字符串”)?;
让name=value.get(“user\u name”).ok\u或(“在json中找不到user\u name属性”)?
.as_str().ok_或(“用户名不是字符串”)?;
Ok(频道{
title:String::from(title),
用户名:字符串::发件人(名称)
})
}
}
//我必须在下面加上一生。请忽略自我参照。
fn获取\u many\u generic>(&self,url\u str:&str)->结果{
//perform_get返回一个serde_json::值
让mut value=&self.perform_get(url_str)?;
如果让值::对象(映射)=值{
value=map.get(“数据”).ok_或(“在需要数组时发现没有“数据”属性的映射”)?;
}
如果let Value::Array(vec)=Value{
Ok(vec.iter()
.filter|u映射(|项|
匹配T::从(项目)中尝试{
好的(模型)=>一些(模型),
错误(e)=>{
println!(“无法反序列化值{}”,项);
没有一个
}
}
).collect())
}
否则{
错误(框::新建)(
错误::新建(格式!({}中的预期数组,但未收到。”,url_str))
))
}
}
我的工作代码:
pub trait TryFromValue where Self: std::marker::Sized {
fn try_from_value(value: &Value) -> Result<Self, Box<dyn Error>>;
}
impl TryFromValue for Channel {
fn try_from_value(value: &Value) -> Result<Channel, Box<dyn Error>> {
let title = value.get("title").ok_or("couldn't find title property in json")?
.as_str().ok_or("title was not a string")?;
let name = value.get("user_name").ok_or("couldn't find user_name property in json")?
.as_str().ok_or("user_name was not a string")?;
Ok(Channel {
title: String::from(title),
user_name: String::from(name)
})
}
}
fn get_many<T: TryFromValue>(&self, url_str: &str) -> Result<Vec<T>, Box<dyn std::error::Error>> {
// perform_get returns a serde_json::Value
let mut value = &self.perform_get(url_str)?;
if let Value::Object(map) = value {
value = map.get("data").ok_or("found a map without a 'data' property when expecting an array")?;
}
if let Value::Array(vec) = value {
Ok(vec.iter()
.filter_map(|item|
match T::try_from_value(item) {
Ok(model) => Some(model),
Err(e) => {
println!("Could not deserialize value {}. Error {}", item, e);
None
}
}
).collect())
}
else {
Err(Box::new(
Error::new(format!("Expected array from {}, but didn't receive one.", url_str))
))
}
}
pub trait TryFromValue,其中Self:std::marker::size{
fn从值(值:&value)->结果尝试;
}
通道的impl TryFromValue{
fn从值(值:&value)->结果尝试{
让title=value.get(“title”).ok_或(“在json中找不到title属性”)?
.as_str().ok_或(“标题不是字符串”)?;
让name=value.get(“user\u name”).ok\u或(“在json中找不到user\u name属性”)?
.as_str().ok_或(“用户名不是字符串”)?;
Ok(频道{
title:String::from(title),
用户名:字符串::发件人(名称)
})
}
}
fn获取\u many(&self,url\u str:&str)->结果{
//perform_get返回一个serde_json::值
让mut value=&self.perform_get(url_str)?;
如果让值::对象(映射)=值{
value=map.get(“数据”).ok_或(“在需要数组时发现没有“数据”属性的映射”)?;
}
如果let Value::Array(vec)=Value{
Ok(vec.iter()
.filter|u映射(|项|
匹配T::从值(项)中尝试{
好的(模型)=>一些(模型),
错误(e)=>{
println!(“无法反序列化值{}。错误{}”,项,e);
没有一个
}
}
).collect())
}
否则{
错误(框::新建)(
错误::新建(格式!({}中的预期数组,但未收到。”,url_str))
))
}
}
为什么这种方法有效,但第一个代码示例失败了?更高的秩特征界限(由trentcl建议)修复了这个问题。查看他们的评论。第一段代码的错误消息是什么?很难回答这个问题,因为当我编译它时,我会遇到一系列关于缺少导入和错误的
&self
参数的错误,但我不知道您看到了什么。请尝试创建一个,最好是on。我强烈怀疑这是(类似问题:,和)的重复。在每种情况下,答案都是使用HRTB。应用于您的问题,这看起来像是fn get\u many\u generic>(…)
@trentcl您是对的,这解决了我的问题。我想是时候重读一下Rustnomicon的那一章了。非常感谢。也很抱歉发布了一个副本。没有理由感到抱歉!重复的问题有时很有用;它们可以联系在一起,帮助未来的提问者更容易地找到答案。很高兴我能帮忙!