如何在Rust中存储不变类型变量 [英] How to store an invariant type variable in Rust
问题描述
我想解析来自tokio-postgresql的一行数据中每个值的类型
I would like to parse the type of each value in a row of data from tokio-postgresql
这里是从PostgreSQL获取一行数据的单个值的示例:
Here is an example of getting a single value for a row of data from postgresql:
...
let rows = client
.query("select * from ExampleTable;")
.await?;
// This is how you read a string if you know the first column is a string type.
let thisValue: &str = rows[0].get(0);
在此示例中,在设计时已知第一列的类型是字符串,因此thisValue
的类型为&str
.我想接受一个不变的类型.
In this example, it is known at design-time that the type in the first column is a string, and therefore the type for thisValue
is &str
. I would like to accept an invariant type.
我打算使用std::any::type_name::<T>()
派生thisValue
中的类型名称,然后使用条件逻辑(if/switch)根据类型对数据进行不同的处理.
I intend to use std::any::type_name::<T>()
to derive the type name in thisValue
and then use conditional logic (if/switch) to process this data differently depending on the type.
在Rust中是否有不变的方式来存储变量? std::any::type_name::<T>()
可以在该变量上工作吗?还有另一种装箱"方式吗?而不是变量?
Is there an invariant way to store a variable in Rust? Will std::any::type_name::<T>()
work on that variable? Is there another way to "box" the variable instead?
我知道std::any::type_name::<T>()
正在使用一种泛型接口.对我来说,这意味着它可能是一种编译时策略,而不是运行时策略.因此,我怀疑我的研究方法是否行得通,但我希望我走在正确的轨道上,只需要最后一块:不变类型.
I understand that std::any::type_name::<T>()
is using a kind of generics interface. To me, this means it's probably a compile-time strategy, not run-time. So I have my doubts that the way I am researching will work, but I hope I am on the right track and only need the final piece: an invariant type.
我应该使用&dyn Any
和TypeId::of::<TypeHere>() == thisValue.type_id()
吗?
在这种情况下,此API tokio-postgresql
的get
函数使用泛型,并且不返回带框的值.因此,在这种情况下,我可能需要使用columns()
确定Rust类型,并使用单独的函数来调用具有不同变量类型的get
.
In this situation, the get
function of this API tokio-postgresql
uses generics and doesn't return a boxed value. Therefore in this situation I may need to use columns()
to determine the Rust type and the use separate functions to call get
with different variables types.
无论我曾经问过标题问题的具体内容如何,仍然需要回答如何在Rust中存储不变类型变量"的总体问题.
The overall question still needs to be answered "How to store an invariant type variable in Rust", regardless of the specifics I have used to ask the title question.
推荐答案
- 首选不变类型为
&dyn any
使用&dyn any
:任何是特征, dyn 表示特征的类型.
With &dyn any
: any is the trait, dyn means the type of the trait.
声明:
let thisValue: &dyn Any = rows[0].get(0); //This works if tokio-postgresql returned a "dyn any" type, which it doesn't
测试引用的类型的示例:
Example of testing what type is referenced:
TypeId::of::<String>() == thisValue.type_id() //type checking using TypeId of boxed value.
使用向下转换测试类型的示例:
Example of testing the type with downcast:
if let Some(string) = thisValue.downcast_ref::<String>() {
println!("String ({}): {}", string.len(), string);
}
- 盒装
Box 强制进行堆分配(如有必要).此策略也包括在内,因此您可以看到&dyn Any
与Boxed
Box to force heap allocation (if necessary). This strategy is included too, so you can see how &dyn Any
works with Boxed
一个装箱"的dyn Any
的值是不变的:
A "boxed" value of dyn Any
is invariant:
let thisValue: Boxed<dyn Any> = rows[0].get(0); //This works if tokio-postgresql returned a "dyn any" type, which it doesn't
在这种情况下,所使用的API需要进行一般的推断,因此对于tokio-postgresql而言,此方法将行不通,但这是标题问题的答案.
In this scenario the API being used requires generic inference, so for tokio-postgresql this won't work, but it is the answer for the title question.
使用Boxed
的downcast
函数测试类型的示例:
An example of testing the type with the downcast
function of Boxed
:
if let Ok(string) = thisValue.downcast::<String>() {
println!("String ({}): {}", string.len(), string);
}
关于postgresql子问题
按照原始帖子
在这种情况下,tokio-postgresql使用此API的get函数 泛型,并且不返回装箱值.因此在这种情况下 我可能需要使用columns()来确定Rust类型和用途 单独的函数来调用具有不同变量类型的get.
In this situation, the get function of this API tokio-postgresql uses generics and doesn't return a boxed value. Therefore in this situation I may need to use columns() to determine the Rust type and the use separate functions to call get with different variables types.
因此,此答案解决了这个问题,尽管它不适用于tokio-postgresql API,但它使您掌握了要查找/构建/等待的那种API的知识.
So this answer solves the question, and although it won't work with the tokio-postgresql API, it equips you with the knowledge of the kind of API you would like to find/build/wait-for.
这篇关于如何在Rust中存储不变类型变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!