Json
std 的 Json 模块做 JSON 与语言值的双向转换:强类型的 Parse / Write,动态的 ParseAny,以及序列化 Stringify。
强类型解析
Json.Parse<T>(s) 按目标类型解析 JSON 文本,失败走 fail Error(错误集 Syntax | MissingField | TypeMismatch):
struct Actor
{
public var name: string = "";
public var hp: int = 0;
}
func main() -> int
{
val text = r#"{"name": "甲", "hp": 7}"#;
print(try? Json.Parse<Actor>(text) == null);
val good = try? Json.Parse<Actor>(text);
print(good?.name, good?.hp);
val captured = capture Json.Parse<Actor>(text);
match captured
{
Success(v) => print(v.name),
Failure(e) => print("失败"),
}
return 0;
}False
甲 7
甲根类型可以是标量、List、Set、Map 或命名 struct / class,enum 根不支持。JSON 里的 null 赋给非空字段一律 TypeMismatch 失败,不会静默漏 null。
避错消费
Json.Parse<T> 是 fail 形,避错用 try?,要失败细节用 capture 收值后 recover 分型,见失败:
val text = r#"{"name": "甲", "hp": 7}"#;
val ok = try? Json.Parse<Actor>(text);
print(ok != null);
val bad = try? Json.Parse<Actor>("{nope");
print(bad == null);True
True序列化
val text = r#"{"name": "甲", "hp": 7}"#;
val good = try? Json.Parse<Actor>(text);
val serialized = try? Json.Stringify(good);
print(serialized);
print(try? Json.StringifyPretty([1, 2], 2));{"name":"\u7532","hp":7}
[
1,
2
]Json.Stringify(v) 输出紧凑 JSON,非 ASCII 字符转义为 \uXXXX,StringifyPretty(v, indent) 带缩进换行。
ParseAny:动态面
类型运行时才知道时,Json.ParseAny(s) fail Error -> any 解析成 any,之后用 is 收窄(见 任意类型(Any)):
val text = r#"{"name": "甲", "hp": 7}"#;
val anyv = try? Json.ParseAny(text);
print(anyv == null);False容器根与错误臂
根类型收 Map(标量键)与 Set,解析失败时 capture 加 match 能拿到错误值本身,ToString() 带模块限定与载荷:
val m = try? Json.Parse<map<string, int>>("{\"甲\": 1, \"乙\": 2}");
print(m?.Count ?? -1);
print(m?.Keys() ?? new list<string>());
val bad = capture Json.Parse<int>("{\"x\":}");
match bad
{
Success(v) => print(v),
Failure(e) => print("解析失败", e),
}2
[甲, 乙]
解析失败 Json.Syntax(pos=5)错误集 Syntax | MissingField | TypeMismatch 各带载荷(Syntax 带出错位置)。按错误类型分臂写 Failure(Syntax(p)) => ... 可以精确分流。
注意
- Json 在 std::Json 模块,通过
Json.前缀免 import 直用。 - 标量键的 Map 可直接参与转换,解析按字段名把 JSON 对象映射到命名类型的字段。
- DateTime 不进 Json walker,持久化走 UnixMicros 整数字段。
最后更新于 2026年10月10日
