如何在 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 Any
和 TypeId::of::<TypeHere>() == thisValue.type_id()
吗?
在这种情况下,此 API tokio-postgresql
的 get
函数使用泛型,而不是 return 盒装值。因此,在这种情况下,我可能需要使用 columns()
来确定 Rust 类型,并使用单独的函数来调用具有不同变量类型的 get
。
总体问题仍然需要回答“How to store an invariant type variable in Rust”,不管我曾经问过标题问题的细节如何。
- 首选不变类型是
&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);
}
- 盒装
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 这将不起作用,但它是标题问题的答案。
用Boxed
的downcast
函数测试类型的例子:
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.
我想解析来自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 Any
和 TypeId::of::<TypeHere>() == thisValue.type_id()
吗?
在这种情况下,此 API tokio-postgresql
的 get
函数使用泛型,而不是 return 盒装值。因此,在这种情况下,我可能需要使用 columns()
来确定 Rust 类型,并使用单独的函数来调用具有不同变量类型的 get
。
总体问题仍然需要回答“How to store an invariant type variable in Rust”,不管我曾经问过标题问题的细节如何。
- 首选不变类型是
&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);
}
- 盒装
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 这将不起作用,但它是标题问题的答案。
用Boxed
的downcast
函数测试类型的例子:
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.