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

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

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

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

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

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

运行时检查

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

介绍自定义特征

可以创建一个新特征:

trait SerializeAsObject : Serialize {}

然后,您只能为那些您确定将被序列化为对象的数据类型实现.但是,没有什么可以阻止你实现i64的特性,所以这里仍有错误的余地.

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

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

关于编译时检查的想法

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

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

点赞