我不想检查类型是否具有特定特征,但我希望能够区分类型,例如一个结构和一个整数。由于结构和整数都可以实现相同的特征,我不知道如何区分它们。
我想这样做的原因是因为我正在使用 serde_json 将通用类型转换为 JSON 但我只希望它成为一个 JSON 对象
(当它是一个结构时会发生)但它不应转换为其他任何东西(如 JSON I64
)。由于结构和整数都可以实现 Serialize
特性,因此无法区分它们。
目前,我让进程 panic ,因为它不是可以从中恢复的错误,但由于我可能在编译时知道这一点,我想知道是否有任何机制可以在编译阶段确定类型。
我想知道如何根据类型而不是特征来区分类型。
最佳答案
即使您设法在编译时比较类型,也没有什么能阻止 struct
被序列化为 Json::I64
。它的 Serialize
实现可以是任何东西!我能想到一些部分解决方案:
运行时检查
添加运行时检查以通过模式匹配查看结果是否确实是 Json::Object
。如果您希望这始终为真,则可以将其与断言结合使用。我认为这就是您现在正在做的事情。
引入自定义特征
可以创建一个新特征:
trait SerializeAsObject : Serialize {}
然后您将只为那些您确定将序列化为对象的数据类型实现。但是,没有什么能阻止您实现 i64
的特性,因此这里仍有出错的余地。
一个真正的解决方案:依赖类型
您可能需要一个支持 dependent types 的类型系统为了确保数据类型的序列化总是产生给定类型的输出。据我所知,这样的类型系统非常复杂,以至于没有广泛使用的语言支持它(如果您想了解更多信息,可以查看 Idris)。
关于编译时检查的思考
虽然编译时检查很棒,但编译器也只能到此为止了。以我的经验,在现实世界的编程中使用依赖类型是不值得的。例如,在这种情况下,您需要提供数学证明,以便编译器可以理解 Serialize
的实现总是导致对象的序列化。
即便如此,也无法确保程序没有错误!因此,我认为在这种情况下,正确的做法是使用断言,记录如果数据无法序列化为对象,您的函数将崩溃,并编写单元测试以确保它被正确调用。
关于types - 是否可以对 Rust 中的泛型进行编译时类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41312320/