当没有类型参数或归属时,如何暗示值的类型? [英] How do I imply the type of the value when there are no type parameters or ascriptions?
问题描述
我正在尝试将我的结构转换为 HashMap
,但是在 impl 块中时我无法这样做.由于板条箱约束,我只能使用&self
作为 resolve
函数的参数.
I am trying to convert my struct into a HashMap
, but I am unable to do so while being in the impl block. Due to a crate constraint, I can only use &self
as a parameter for the resolve
function.
use std::collections::HashMap;
pub enum Value {
Int(i64),
Object(HashMap<String, Value>),
}
pub struct WeatherSettings {
forecast_days: i64,
}
impl WeatherSettings {
fn resolve(&self) -> Value {
let json_object: HashMap<String, Value> = *self.into();
Value::Object(json_object)
}
}
impl From<WeatherSettings> for HashMap<String, Value> {
fn from(weather: WeatherSettings) -> HashMap<String, Value> {
let mut json_object = HashMap::new();
json_object.insert("forecast_days".to_owned(),
Value::Int(weather.forecast_days));
return json_object;
}
}
fn main() {}
更直接,我得到错误:
error: the type of this value must be known in this context
--> src/main.rs:14:51
|
14 | let json_object: HashMap<String, Value> = *self.into();
| ^^^^^^^^^^^^
推荐答案
当没有类型参数或归属时,如何暗示值的类型?
How do I imply the type of the value when there is no type parameters or ascriptions?
在绝大多数情况下,Rust 编译器可以根据泛型类型的值的使用方式来推断类型或函数的泛型类型.
In the vast majority of cases, the Rust compiler can infer the generic types of a type or function based on how values of the generic type are used.
在某些情况下,没有足够的信息来推断泛型类型的确切类型,但总有一种方法可以在类型参数存在时传递它们.
In some cases, there isn't enough information to infer exactly one type for a generic type, but there is always a way to pass type parameters when they exist.
这样做的两种方法是使用 turbofish 或 完全限定语法呼叫站点.
The two ways of doing so are to use the turbofish or fully qualified syntax at the call site.
turbofish 是附加到函数或类型的符号 ::<Type1, Type2, ...>
.看看它看起来像一条鱼吗?
The turbofish is the symbols ::<Type1, Type2, ...>
appended to a function or type. See how it looks like a fish?
mem::size_of
定义为:
pub const fn size_of<T>() -> usize.
您可以将其称为:
std::mem::size_of::<i8>()
// ^^^^^^ turbofish
类型示例
Vec::new代码>
定义为:
impl<T> Vec<T> {
pub fn new() -> Vec<T>
}
您可以将其称为:
Vec::<u8>::new()
// ^^^^^^ turbofish
多种类型
如果你的函数有多种类型,你需要按照定义的顺序为每种类型指定一些东西:
Multiple types
If your function has multiple types, you need to specify something for each type in the same order as the definition:
fn example<A, B>() {}
fn main() {
example::<i32, bool>();
// ^A ^B
}
完全限定的语法
如果您需要使用类型参数消除对特定特征的方法调用的歧义,您可以使用完全限定的语法.
Fully qualified syntax
If you need to disambiguate a method call to a specific trait with a type parameter, you can use the fully qualified syntax.
From::from代码>
定义为:
trait From<T> {
fn from(T) -> Self;
}
您可以将其称为:
<String as From<&str>>::from("a")
// ^^^^^^^^^^^^^^^^^^^^^^ fully qualified syntax
部分推断类型
如果可以提供多种类型,但其中一些可以推断,您仍然可以使用 _
来允许编译器推断该特定类型.
Partially inferring types
If there are multiple types that can be provided but some of them can be inferred, you can still use _
to allow the compiler to infer that specific type.
这里,我使用 Into
类型上的 turbofish 为您的代码:
Here, I use the turbofish on the Into
type for your code:
let json_object = *Into::<HashMap<String, Value>>::into(self);
不过那不是你的问题.
为了使这一行有效:
let json_object: HashMap<String, Value> = *self.into();
调用 self.into()
的结果必须是可以取消引用以产生 HashMap
类型的东西.编译器如何知道那是什么?这也不是你想要的.
The result of the call to self.into()
must be something that could be dereferenced to produce the type HashMap<String, Value>
. How is the compiler expected to know what that is? It's also not what you want.
你所拥有的只是&self
,所以这就是你必须转换的.实现 trait 以引用您的结构:
All you have is &self
, so that's what you have to convert from. Implement the trait for a reference to your struct:
impl<'a> From<&'a WeatherSettings> for HashMap<String, Value> {
fn from(weather: &'a WeatherSettings) -> HashMap<String, Value> {
let mut json_object = HashMap::new();
json_object.insert("unit".to_owned(), Value::String(weather.unit.clone()));
json_object.insert("forecast_days".to_owned(), Value::Int(weather.forecast_days));
json_object.insert("data".to_owned(), Value::String(weather.data.clone()));
json_object
}
}
这意味着您不能移动字符串,而必须复制它们.这是 &self
的限制.
This means you cannot move the strings over, but instead have to copy them. That's the restriction placed by the &self
.
这篇关于当没有类型参数或归属时,如何暗示值的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!