是否可以对Rust中的泛型进行编译时类型检查?

时间:2016-12-24 10:10:43

标签: types rust

我不想检查某种类型是否具有某种特征,但我希望能够区分,例如:结构和整数。由于结构和整数都可以实现相同的特性,我不知道如何区分它们。

我想这样做的原因是因为我使用serde_json将泛型类型转换为JSON但我希望它成为JSON Object(当它发生时)是一个结构)但它不应该转换为任何其他东西(如JSON I64)。由于结构和整数都可以实现Serialize特性,因此没有办法区分它们。

目前,我让这个过程感到恐慌,因为它不是一个可以恢复的错误,但由于我可能在编译时知道这一点,我想知道在编译阶段是否有任何机制来确定类型。< / p>

我想知道如何通过他们的“善意”而不是他们的特质来区分类型。

1 个答案:

答案 0 :(得分:2)

即使您在编译时设法比较了这些类型,也没有什么能阻止struct被序列化为Json::I64。它的Serialize实现可以是任何东西!我可以想到一些部分解决方案:

运行时检查

通过模式匹配添加运行时检查以查看结果是否确实是Json::Object。您可以将此与断言相结合,以防您希望此操作始终为真。我想这就是你现在正在做的事情。

介绍自定义特征

可以创建一个新特征:

trait SerializeAsObject : Serialize {}

然后,您只能为那些您确定将被序列化为对象的数据类型实现。但是,没有什么可以阻止您实现i64的特征,因此这里仍然存在错误的空间。

真正的解决方案:依赖类型

您可能需要一个支持dependent types的类型系统,以确保数据类型的序列化始终产生给定类型的输出。据我所知,这种类型的系统非常复杂,没有广泛使用的语言支持它(你可以看一下Idris,以防你想了解更多这方面的内容。)

关于编译时检查的想法

虽然编译时检查很棒,但编译器只能到目前为止。根据我的经验,在现实世界编程中使用依赖类型是不值得的麻烦。例如,在这种情况下,您需要提供数学证明,以便编译器可以理解Serialize的实现总是导致对象的序列化。

即便如此,也无法确保程序没有错误!因此,我认为在这种情况下,正确的做法是使用断言,文档,如果数据不能被序列化为对象,您的函数将会出现混乱,并编写单元测试以确保正确调用它。