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

Types 是否可以对Rust中的泛型执行编译时类型检查?,types,rust,Types,Rust,我不想检查类型是否具有某种特征,但我希望能够区分,例如,结构和整数。由于结构和整数都可以实现相同的特性,我不知道如何区分它们 我之所以要这样做,是因为我正在使用serde_json将泛型类型转换为json,但我只希望它成为json对象(当它是一个结构时会发生这种情况),但它不应该转换为任何其他类型(如jsonI64)。由于结构和整数都可以实现序列化特性,因此无法区分它们 目前,我让进程惊慌失措,因为它不是一个可以恢复的错误,但由于我可能在编译时知道这一点,我想知道是否有任何机制可以在编译阶段确定

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

我之所以要这样做,是因为我正在使用serde_json将泛型类型转换为json,但我只希望它成为json
对象(当它是一个结构时会发生这种情况),但它不应该转换为任何其他类型(如json
I64
)。由于结构和整数都可以实现
序列化特性,因此无法区分它们

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


我想知道如何根据类型的“种类”而不是特征来区分类型。

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

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

引入一种习惯特征 有可能创造出一种新的特质:

trait SerializeAsObject : Serialize {}
然后,您将只为那些您确信将被序列化为对象的数据类型实现。但是,没有什么可以阻止您实现
i64
的trait,因此这里仍然有出错的空间

真正的解决方案:依赖类型 您可能需要一个类型系统支持,以确保数据类型的序列化总是导致给定类型的输出。据我所知,这样一个类型系统是如此复杂,以至于没有广泛使用的语言支持它(如果您想了解更多信息,可以看看)

关于编译时检查的思考 虽然进行编译时检查很好,但编译器只能做到这一点。根据我的经验,在现实编程中使用依赖类型不值得这么麻烦。例如,在本例中,您需要提供数学证明,以便编译器能够理解
Serialize
的实现总是导致对象的序列化


即使这样,也无法确保程序没有bug!因此,我认为在这种情况下,正确的做法是使用断言,记录如果数据无法序列化为对象,函数将崩溃,并编写单元测试以确保正确调用它。

你完全正确。因此,“类型检查”结构不是示例的正确解决方案。模式匹配需要在运行时完成,这是不幸的。太糟糕了,我需要让进程为一些原则上可以在编译时知道的东西而惊慌失措。有很多在编译时知道的东西被扔掉了。即使是在支持代码推理的语言中,想象一下程序员向编译器解释他们的意图是多么困难。这变得非常复杂,非常快。你必须写一个数学证明,证明编译器能够理解。我同意。在这种情况下,更实用的运行时解决方案应该不是问题。Aochagavia刚刚向我指出,在我的示例中,比较类型并不能解决问题。我仍然希望这个问题能说明问题所在。我想没有优雅的解决方案,我只需要在运行时进行验证。或者可以用一个过程宏来解决,但这似乎有点过头了。您需要找到一种方法让编译器检查:“我知道序列化的这个实现总是返回对象”。