从外部函数中的螺栓数据库解组 json 时出现意外故障地址错误

Getting unexpected fault address error when unmarshalling json from bolt database in external function

我目前正在使用 Go 中的 Bolt 数据库处理 storing/retrieving 个字符。
我在这里写了这个函数来检索存储的每个字符并且它工作正常。

//this works fine
func GetAllCharacters() []Character {
    var charList []Character
    var char Character

    db, err := bolt.Open("./savedata/database.db", 0600, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    err = db.View(func(tx *bolt.Tx) error {
        c := tx.Bucket([]byte("DB")).Bucket([]byte("Characters")).Cursor()

        for k, v := c.First(); k != nil; k, v = c.Next() {
            err := json.Unmarshal(v, &char)
            if err != nil {
                log.Fatal(err)
            }
            charList = append(charList, char)
        }

        return nil
    })

    if err != nil {
        log.Fatal(err)
    }

    return charList
}

然后我想稍微清理一下我的代码并将函数的一部分移到另一个文件中,如下所示:

实用程序文件:

package utils

func GetAllCharactersFromDB() [][]byte {
    var charList [][]byte

    db, err := bolt.Open("./savedata/database.db", 0600, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    err = db.View(func(tx *bolt.Tx) error {
        c := tx.Bucket([]byte("DB")).Bucket([]byte("Characters")).Cursor()

        for k, v := c.First(); k != nil; k, v = c.Next() {
            charList = append(charList, v)
        }

        return nil
    })

    if err != nil {
        log.Fatal(err)
    }

    return charList
}

主文件:

func GetAllCharacters() []Character {
    var charList []Character
    var char Character

    allChars := utils.GetAllCharactersFromDB()

    for _, v := range allChars {
        err := json.Unmarshal(v, &char)
        if err != nil {
            log.Fatal(err)
        }
        charList = append(charList, char)
    }

    return charList
}

现在,当我尝试 运行 这段代码时,我收到一条我无法真正解密的神秘错误消息:

unexpected fault address 0x20d5607405f
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0x20d5607405f pc=0xa4ba35]

goroutine 1 [running]:
runtime.throw({0xa93ef9, 0x20d30d50108})
        C:/Program Files/Go/src/runtime/panic.go:1198 +0x76 fp=0xc0001096a0 sp=0xc000109670 pc=0x9b4b16
runtime.sigpanic()
        C:/Program Files/Go/src/runtime/signal_windows.go:260 +0x10c fp=0xc0001096e8 sp=0xc0001096a0 pc=0x9c606c
encoding/json.checkValid({0x20d5607405f, 0x27a, 0x1}, 0xc00011c0b8)
        C:/Program Files/Go/src/encoding/json/scanner.go:32 +0xb5 fp=0xc000109710 sp=0xc0001096e8 pc=0xa4ba35
encoding/json.Unmarshal({0x20d5607405f, 0xac2ec0, 0xc000006010}, {0xa8b400, 0xc000118120})
        C:/Program Files/Go/src/encoding/json/decode.go:101 +0x5a fp=0xc000109758 sp=0xc000109710 pc=0xa3cc9a
github.com/my_name/gotestgame/game.GetAllCharacters()
        C:/Users/my_name/Documents/Golang/simplegame/game/characters.go:164 +0xcc fp=0xc000109808 sp=0xc000109758 pc=0xa63b4c
github.com/my_name/gotestgame/game.Leaderboard()
        C:/Users/my_name/Documents/Golang/simplegame/game/level.go:125 +0xab fp=0xc000109d20 sp=0xc000109808 pc=0xa6782b
github.com/my_name/gotestgame/game.MainMenu()
        C:/Users/my_name/Documents/Golang/simplegame/game/menu.go:58 +0x3ba fp=0xc000109f60 sp=0xc000109d20 pc=0xa699da
main.main()
        C:/Users/my_name/Documents/Golang/simplegame/main.go:16 +0x4a fp=0xc000109f80 sp=0xc000109f60 pc=0xa6d4ea
runtime.main()
        C:/Program Files/Go/src/runtime/proc.go:255 +0x217 fp=0xc000109fe0 sp=0xc000109f80 pc=0x9b70d7
runtime.goexit()
        C:/Program Files/Go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000109fe8 sp=0xc000109fe0 pc=0x9df7e1
exit status 2

谁能告诉我为什么新方法不起作用?我可以做些什么来让它发挥作用?我认为 json.Unmarshal 在这两种情况下都会解组相同的 []byte ,还是我错了?当我在 GetAllCharactersFromDB() 函数中打印出 string(v) 的内容时,我得到了一个可读的 json 字符串。这不是很紧急,因为第一个代码片段有效,但令我困扰的是我无法弄清楚为什么第二种方法不起作用。抱歉,如果这是一个愚蠢的问题,我是 Go 的新手。

编辑:

作为对评论的回应,Character 的外观如下:

type Character struct {
    Name         string `json:"name"`
    Hardcore     bool   `json:"hardcore"`
    Default      bool   `json:"default"`
    Level        int    `json:"level"`
    XP           int    `json:"xp"`
    Class        string `json:"class"`
    Max_HP       int    `json:"max_hp"`
    Current_HP   int    `json:"current_hp"`
    Strength     int    `json:"str"`
    Dexterity    int    `json:"dex"`
    Intelligence int    `json:"int"`
    Gold         int    `json:"gold"`
    Weapon       Weapon `json:"weapon"`
    Items        []Item `json:"items"`
}

存储的数据如下所示:

{"name":"Test1","hardcore":true,"default":true,"level":1,"xp":1,"class":"Barbarian","max_hp":150,"current_hp":150,"str":30,"dex":15,"int":5,"gold":0,"weapon":{"Name":"Rusty Club","Description":"Starter Weapon for the Barbarian.","Rarity":{"Common":1,"Uncommon":0,"Rare":0,"Epic":0,"Legendary":0},"LowAttack":15,"HighAttack":40,"AttackSpeed":1.2,"CritChance":5,"Accuracy":95,"Range":10,"ReqStr":15,"ReqDex":5,"ReqInt":0,"BuyPrice":30,"SellPrice":1},"items":[{"Name":"Small Healing Potion","Description":"Heals you for 20 HP","Tag":"Heal","Rarity":{"Common":1,"Uncommon":0,"Rare":0,"Epic":0,"Legendary":0},"BuyPrice":25,"SellPrice":1}]}

请尝试替换以下行:

charList = append(charList, v)

vc := make([]byte, len(v))
copy(vc,v)
charList = append(charList, vc)