我正在编写一个web应用程序,并通过索尼反序列化为规范模型对象类型.范数-模型类型总是引用对象.不知何故,我的代码(非常类似于jsony的github文档中的默认示例)没有编译。相反,我收到错误SIGSEGV: Illegal storage access. (Attempt to read from nil?)。
看这里我的代码示例
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示例看起来非常相似:
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"我怎么才能解决这个问题?
发布于 2022-05-14 06:39:55
答案在于,规范对象类型是ref对象,而不是普通(值)对象(感谢ElegantBeef、Rika和Yardanico从nim-不和谐中指出这一点)!如果您没有在某一点上显式地“创建”一个ref类型,那么它的内存就不会被分配,因为代码不会为您分配内存,而不像使用值类型那样!
因此,您必须先初始化/创建一个ref对象,然后才能使用它,而Jsony不负责初始化!
因此,编写上述newHook的正确方法如下所示:
proc newHook*(entry: var Character) =
entry = new(Character)
let currentDateTime: DateTime = now()
entry.creation_datetime = currentDateTime
entry.update_datetime = currentDateTime
entry.name = ""https://stackoverflow.com/questions/72237922
复制相似问题