0

我目前正在从 Go 中的 Bolt 数据库中存储/检索字符。
我在这里编写了这个函数来检索存储的每个字符,它工作正常。

//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的,还是我错了?当我打印出函数string(v)中的内容时,GetAllCharactersFromDB()我得到一个可读的 json 字符串。由于第一个代码片段有效,这并不是很紧急,但令我困扰的是,我无法弄清楚为什么第二种方法不起作用。抱歉,如果这是一个愚蠢的问题,我对 Go 还是很陌生。

编辑:

作为对评论的回应,下面是 a 的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}]}
4

1 回答 1

2

请尝试替换以下行:

charList = append(charList, v)

vc := make([]byte, len(v))
copy(vc,v)
charList = append(charList, vc)
于 2022-01-04T16:01:58.247 回答