如何在Rust中存储不变类型变量 [英] How to store an invariant type variable in Rust

查看:124
本文介绍了如何在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 AnyTypeId::of::<TypeHere>() == thisValue.type_id()吗?

在这种情况下,此API tokio-postgresqlget函数使用泛型,并且不返回带框的值.因此,在这种情况下,我可能需要使用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.

推荐答案

  1. 首选不变类型为&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);
}

  1. 盒装

Box 强制进行堆分配(如有必要).此策略也包括在内,因此您可以看到&dyn AnyBoxed

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.

使用Boxeddowncast函数测试类型的示例:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆