首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jsony newHook拥有“`SIGSEGV:非法存储访问”。(尝试从nil读取?)当反序列化为ref对象时

Jsony newHook拥有“`SIGSEGV:非法存储访问”。(尝试从nil读取?)当反序列化为ref对象时
EN

Stack Overflow用户
提问于 2022-05-14 06:39:55
回答 1查看 162关注 0票数 0

我正在编写一个web应用程序,并通过索尼反序列化为规范模型对象类型.范数-模型类型总是引用对象.不知何故,我的代码(非常类似于jsony的github文档中的默认示例)没有编译。相反,我收到错误SIGSEGV: Illegal storage access. (Attempt to read from nil?)

看这里我的代码示例

代码语言:javascript
复制
import std/[typetraits, times]
import norm/[pragmas, model]
import jsony

const OUTPUT_TIME_FORMAT* = "yyyy-MM-dd'T'HH:mm:ss'.'ffffff'Z'"
type Character* {.tableName: "wikientries_character".} = ref object of Model
    name*: string
    creation_datetime*: DateTime
    update_datetime*: DateTime

proc parseHook*(s: string, i: var int, v: var DateTime) =
    ##[ jsony-hook that is automatically called to convert a json-string to datetime
    
    ``s``: The full JSON string that needs to be serialized. Your type may only be a part of this
    ``i``: The index on the JSON string where the next section of it starts that needs to be serialized here
    ``v``: The variable to fill with a proper value]##
    var str: string
    s.parseHook(i, str)
    v = parse(s, OUTPUT_TIME_FORMAT, utc())

proc newHook*(entry: var Character) =
  let currentDateTime: DateTime = now()
  entry.creation_datetime = currentDateTime # <-- This line is listed as the reason for the sigsev
  entry.update_datetime = currentDateTime
  entry.name = ""
  
var input = """ {"name":"Test"} """

let c = input.fromJson(Character)

我不明白这里的问题是什么,因为它的github页面上的jsony示例看起来非常相似:

代码语言:javascript
复制
type
  Foo5 = object
    visible: string
    id: string
proc newHook*(foo: var Foo5) =
  # Populates the object before its fully deserialized.
  foo.visible = "yes"

var s = """{"id":"123"}"""
var v = s.fromJson(Foo5)
doAssert v.id == "123"
doAssert v.visible == "yes"

我怎么才能解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-14 06:39:55

答案在于,规范对象类型是ref对象,而不是普通(值)对象(感谢ElegantBeef、Rika和Yardanico从nim-不和谐中指出这一点)!如果您没有在某一点上显式地“创建”一个ref类型,那么它的内存就不会被分配,因为代码不会为您分配内存,而不像使用值类型那样!

因此,您必须先初始化/创建一个ref对象,然后才能使用它,而Jsony不负责初始化!

因此,编写上述newHook的正确方法如下所示:

代码语言:javascript
复制
proc newHook*(entry: var Character) =
  entry = new(Character)
  let currentDateTime: DateTime = now()
  entry.creation_datetime = currentDateTime
  entry.update_datetime = currentDateTime
  entry.name = ""
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72237922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档