# js backend 当中对于 Option\[T\] 是如何存储的

**URL:** <https://taolun.moonbitlang.com/t/topic/991>\
**Category:** 代码帮助\
**Created:** [2024 年10 月 16 日 20:46 UTC](https://taolun.moonbitlang.com/t/topic/991 "2024-10-16T20:46:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

作者： ![tiye](https://taolun.moonbitlang.com/user_avatar/taolun.moonbitlang.com/tiye/32/401_2.png) [@tiye](https://taolun.moonbitlang.com/u/tiye)\
发布日期： [2024 年10 月 16 日 20:46 UTC](https://taolun.moonbitlang.com/t/topic/991/1 "2024-10-16T20:46:00Z")

</div>

问题的来源是我把这个数据 json stringify 存到 localStorage 当中了, 然后取出来

[https://github.com/Respo/respo.mbt/blob/main/src/lib/states-tree.mbt#L8](https://github.com/Respo/respo.mbt/blob/main/src/lib/states-tree.mbt#L8)

多次重复之后发现嵌套的数组非常深.

 ![image](https://taolun.moonbitlang.com/uploads/default/original/1X/7b4b684ae76e5c61c86d3161d1e73ee1d4257d48.png)

猜想是跟 json stringify 的实现有关, 有观察到 `[v]` `undefined` 被用在表示 `Option[T]` 相关的值. 不确定.

实际的问题估计还是在我自己的逻辑当中. 但想了解一下关于 `Option[T]` 的实现方式用于排查问题. 以及对此是否有推荐的最佳实践.

---

<div class="post-metadata">

作者： ![ChenYubin](https://taolun.moonbitlang.com/letter_avatar_proxy/v4/letter/c/ee59a6/32.png) [@ChenYubin](https://taolun.moonbitlang.com/u/ChenYubin)\
发布日期： [2024 年10 月 17 日 02:23 UTC](https://taolun.moonbitlang.com/t/topic/991/2 "2024-10-17T02:23:57Z")

</div>

有没有能够产生这个输出的具体代码呢？当field的类型是Option[V]时， ToJson会将其处理为`field: v` 或 `undefined`。看这里的类型`@json.JsonValue?`不像是会得到这种输出。

---

<div class="post-metadata">

作者： ![ChenYubin](https://taolun.moonbitlang.com/letter_avatar_proxy/v4/letter/c/ee59a6/32.png) [@ChenYubin](https://taolun.moonbitlang.com/u/ChenYubin)\
发布日期： [2024 年10 月 17 日 03:01 UTC](https://taolun.moonbitlang.com/t/topic/991/3 "2024-10-17T03:01:33Z")

</div>

仔细看了一下，原来是手动实现的to\_json和from\_json不对称。

> <https://github.com/Respo/respo.mbt/blob/81fe8c0ee196b9a4fb5ed5ea58ec02e98eb7a727/src/lib/states-tree.mbt#L45>

这一行Map::get返回的是Option[V]，而不是V。所以from\_json(to\_json(x))了以后data字段的value会多套一层`[]`，猜测这个输出是反复输出和读入json导致的。

比较尴尬的是Json类型实现了ToJson Trait，但是漏了FromJson，所以目前也不能直接对RespoStatesTree `derive(ToJson,FromJson)`。手写的from\_json可以改成：

```auto
pub impl @json.FromJson for RespoStatesTree with from_json(json, path) {
  match json {
    { "data": data, "cursor": cursor, "branches": branches } => {
      // data: @json.from_json!(data, path=path.add_key("data")), // Json FromJson not implemented yet
      data: match data {
        [v] => Some(v)
        _ => None
      },
      cursor: @json.from_json!(cursor, path=path.add_key("cursor")),
      branches: @json.from_json!(branches, path=path.add_key("branches")),
    }
    _ => raise @json.JsonDecodeError((path, "unexpected json"))
  }
}

```

这里使用了Json pattern。

---

<div class="post-metadata">

作者： ![tiye](https://taolun.moonbitlang.com/user_avatar/taolun.moonbitlang.com/tiye/32/401_2.png) [@tiye](https://taolun.moonbitlang.com/u/tiye)\
发布日期： [2024 年10 月 17 日 03:09 UTC](https://taolun.moonbitlang.com/t/topic/991/4 "2024-10-17T03:09:46Z")

</div>

感谢. 本来想着把 JSON 结构跟数据对对上然后缩小范围自己查的. 现在处理 `Json?` 的场景也还不熟练, 我理解一下.
