Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 枚举上的Serde untagged属性导致堆栈溢出_Rust_Serde - Fatal编程技术网

Rust 枚举上的Serde untagged属性导致堆栈溢出

Rust 枚举上的Serde untagged属性导致堆栈溢出,rust,serde,Rust,Serde,Im使用枚举上的untaged属性来序列化和反序列化JSON //这只是一个使用“untaged”的示例—不是问题的实际代码。 #[派生(序列化、反序列化)] #[塞尔德(未标记)] 枚举消息{ 串(串),, X(X), } 我在运行时遇到一个致命的运行时错误:对于我的某些类型,堆栈溢出 通过使用Box,这些类型可能具有递归定义 通常,当使用未标记属性时,什么会导致堆栈溢出 这些文档没有说明任何限制,因此它似乎适用于任何编译的代码 这是我在Mac OS上用Instruments/Sampler

Im使用枚举上的
untaged
属性来序列化和反序列化JSON

//这只是一个使用“untaged”的示例—不是问题的实际代码。
#[派生(序列化、反序列化)]
#[塞尔德(未标记)]
枚举消息{
串(串),,
X(X),
}
我在运行时遇到一个
致命的运行时错误:对于我的某些类型,堆栈溢出

通过使用
Box
,这些类型可能具有递归定义

通常,当使用
未标记属性时,什么会导致堆栈溢出

这些文档没有说明任何限制,因此它似乎适用于任何编译的代码

这是我在Mac OS上用Instruments/Sampler收集的堆栈跟踪,
\uuuu rust\u probestack
似乎是最后一个调用的函数,此时它大约有70个函数深


根据您在评论中所说的,您有递归类型。问题来自
未标记的
工作方式。下面是一个再现问题的最小示例:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum Foo {
    Foo(Box<Foo>),
    Bar(String),
}

fn main() {
    let data = r#""Bar""#;

    let _v: Foo = serde_json::from_str(&data).unwrap();
}

根据您在评论中所说的,您有递归类型。问题来自
未标记的
工作方式。下面是一个再现问题的最小示例:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum Foo {
    Foo(Box<Foo>),
    Bar(String),
}

fn main() {
    let data = r#""Bar""#;

    let _v: Foo = serde_json::from_str(&data).unwrap();
}

通过将堆栈设置为16MB进行修复:

export RUST\u MIN\u STACK=16777216和货物测试

通过将堆栈设置为16MB进行修复:



export RUST\u MIN\u STACK=16777216&&cargo test

您是否可以更新代码以包括
参数
,以及再现问题的示例(可选链接到)。这只是使用
未标记
属性的示例,该示例不会触发堆栈溢出。我不太清楚是什么导致了这个问题。我的代码库有相当多的结构,我不知道如何用最少的代码来复制它。听起来是时候真正创建一个最小的复制了。您要做的是删除程序的某些部分(不必要的结构字段等),除了那些使问题消失的部分,然后继续执行,直到您有了一个小程序(尽管对于您的原始目标来说没有意义)。最后,这个问题很可能对你来说是显而易见的!如果它在Serde中被认为是一个bug,那么现在你就有了bug报告的材料。堆栈溢出仅仅意味着你在堆栈上放的数据比空间还多。在类Unix操作系统上,可以使用
ulimit-s
查看堆栈大小(以千字节为单位)。你也可以为你的工作增加它,看看是否能解决它。最常见的处理方法是将数据放在堆上而不是堆栈上。您是否有任何迹象表明
未标记
标志与堆栈溢出有关?您是否可以更新代码以包括
参数
,以及重现问题的示例(可选链接到)这只是使用
untaged
属性的一个示例,该示例不会触发
堆栈溢出。我不太清楚是什么导致了这个问题。我的代码库有相当多的结构,我不知道如何用最少的代码来复制它。听起来是时候真正创建一个最小的复制了。您要做的是删除程序的某些部分(不必要的结构字段等),除了那些使问题消失的部分,然后继续执行,直到您有了一个小程序(尽管对于您的原始目标来说没有意义)。最后,这个问题很可能对你来说是显而易见的!如果它在Serde中被认为是一个bug,那么现在你就有了bug报告的材料。堆栈溢出仅仅意味着你在堆栈上放的数据比空间还多。在类Unix操作系统上,可以使用
ulimit-s
查看堆栈大小(以千字节为单位)。你也可以为你的工作增加它,看看是否能解决它。最常见的处理方法是将数据放在堆而不是堆栈上。您是否有任何迹象表明
untaged
标志与堆栈溢出有关?谢谢。在我的代码中,像字符串这样的标量值排在第一位,枚举只包含精确的结构-所以这些应该停止递归?结构可能包含枚举并再次递归,但是
untaged
不会逐级匹配输入JSON(并且不会在不确保JSON可以在每个级别匹配的情况下递归到更深的级别)?例如,这为什么不会导致堆栈溢出?JSON中没有标识结构的内容。如果可以解析结构,则结构“匹配”,因此如果结构中的第一个字段是未标记的枚举,则Serde将立即递归。您的示例不会溢出,因为每个结构的第一个字段都是标记,因此当当前级别没有标记时,递归就会停止(这也是Serde的标准枚举的工作方式).但是structs+JSON结尾的标记仍然有效:谢谢。在我的代码中,像字符串这样的标量值排在第一位,枚举只包含精确的结构-所以这些应该停止递归?结构可能包含枚举并再次递归,但是
untaged
不会逐级匹配输入JSON(并且不会在不确保JSON可以在每个级别匹配的情况下递归到更深的级别)?例如,这为什么不会导致堆栈溢出?JSON中没有标识结构的内容。如果可以解析结构,则结构“匹配”,因此如果结构中的第一个字段是未标记的枚举,则Serde将立即递归。您的示例不会溢出,因为每个结构的第一个字段都是标记,因此当当前级别没有标记时,递归就会停止(这也是Serde的标准枚举的工作方式).但structs+JSON结尾的标记仍然有效: