如何在 Rust 中存储不变类型变量

How to store an invariant type variable in Rust

我想解析来自tokio-postgresql

的一行数据中每个值的类型

下面是从 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);

在此示例中,在 design-time 处已知第一列中的类型是字符串,因此 thisValue 的类型是 &str。我想接受不变类型。

我打算使用std::any::type_name::<T>()导出thisValue中的类型名称,然后使用条件逻辑(if/switch)根据类型不同地处理此数据。

在 Rust 中是否有一种不变的方式来存储变量? std::any::type_name::<T>() 会处理那个变量吗?有没有另一种方法来“装箱”变量?

我了解到 std::any::type_name::<T>() 正在使用一种泛型接口。对我来说,这意味着它可能是 compile-time 策略,而不是 run-time。所以我怀疑我正在研究的方式是否可行,但我希望我走在正确的轨道上并且只需要最后一块:不变类型。

我应该使用 &dyn AnyTypeId::of::<TypeHere>() == thisValue.type_id() 吗?

在这种情况下,此 API tokio-postgresqlget 函数使用泛型,而不是 return 盒装值。因此,在这种情况下,我可能需要使用 columns() 来确定 Rust 类型,并使用单独的函数来调用具有不同变量类型的 get

总体问题仍然需要回答“How to store an invariant type variable in Rust”,不管我曾经问过标题问题的细节如何。

  1. 首选不变类型是&dyn any

With &dyn any: any is the trait, dyn表示特征的类型。

正在声明:

let thisValue: &dyn Any = rows[0].get(0); //This works if tokio-postgresql returned a "dyn any" type, which it doesn't

测试引用什么类型的示例:

TypeId::of::<String>() == thisValue.type_id() //type checking using TypeId of boxed value.

使用向下转换测试类型的示例:

if let Some(string) = thisValue.downcast_ref::<String>() {
    println!("String ({}): {}", string.len(), string);
}
  1. 盒装

Box 强制堆分配(如果需要)。这个策略也包括在内,所以你可以看到 &dyn Any 如何与 Boxed

一起工作

dyn Any 的“盒装”值是不变的:

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 这将不起作用,但它是标题问题的答案。

Boxeddowncast函数测试类型的例子:

if let Ok(string) = thisValue.downcast::<String>() {
    println!("String ({}): {}", string.len(), string);
}

关于postgresql sub-problem

按照原文post,

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 类型的知识至 find/build/wait-for.