gpt4 book ai didi

google-app-engine - 采空区 : interface is only registered on Encode but not on Decode

转载 作者:数据小太阳 更新时间:2023-10-29 03:16:34 25 4
gpt4 key购买 nike

我正在使用数据存储开发应用引擎应用程序。我正在尝试采空对接口(interface)进行编码并将其存储到数据存储中。但是当我尝试从加载数据存储,我收到错误:

gob: name not registered for interface: "main27155.strand"

奇怪的是 load() 方法在加载后开始工作调用了 save() 方法。它不再返回错误,一切都保存了在数据存储中按预期加载。但是当我重新启动实例时,load() 方法再次停止工作。

我提到的加载和保存方法是指定义的方法datastore.PropertyLoadSaver 接口(interface)

从外观上看,注册似乎有问题与 gob 的类型/接口(interface),但我有完全相同的 gob.Register() 调用load()save() 方法。

我什至尝试从加载和保存方法中删除 gob.Register() 调用并将其添加到 init()。观察到完全相同的行为。

如何在冷启动时加载我的数据存储?

type bio struct {¬                          
Id string¬
Hp int¬
godie chan bool //should be buffered¬
dam chan int¬
Genetics dna¬


type dna interface {
decode() mRNA
Get(int) trait
Set(int, trait)
Duplicate() dna
Len() int
}
type trait interface {
mutate() trait
}

// implements dna{}
type strand []trait

// implements trait{}
type tdecoration string
type color struct {
None bool // If true, colors are not shown in theme
Bg bool // If true, color is a background color
R int // 0-255
G int
B int
}

.

func start(w http.ResponseWriter, r *http.Request) error {
c := appengine.NewContext(r)

var bs []bio
if _, err := datastore.NewQuery("bio").GetAll(c, &bs); err != nil {
log.Println("bs is len: ", len(bs))
return err
}

...
return nil
}

func stop(w http.ResponseWriter, r *http.Request) error {
c := appengine.NewContext(r)
log.Println("Saving top 20 colors")
var k []*datastore.Key
var bs []*bio
stat := getStats()
for i, b := range stat.Leaderboard {
k = append(k, datastore.NewKey(c, "bio", b.Id, 0, nil))
bv := b
bs = append(bs, &bv)
// At most 20 bios survive across reboots
if i > 178 {
break
}
}

// Assemble slice of keys for deletion
dk, err := datastore.NewQuery("bio").KeysOnly().GetAll(c, nil)
if err != nil {
return errors.New(fmt.Sprintf("Query error: %s", err.Error()))
}

fn := func(c appengine.Context) error {
// Delete all old entries
err := datastore.DeleteMulti(c, dk)
if err != nil {
return errors.New(fmt.Sprintf("Delete error: %s", err.Error()))
}

// save the elite in the datastore
_, err = datastore.PutMulti(c, k, bs)
if err != nil {
return err
}
return nil
}

return datastore.RunInTransaction(c, fn, &datastore.TransactionOptions{XG: true})
}

// satisfy datastore PropertyLoadSaver interface ===============================

func (b *bio) Load(c <-chan datastore.Property) error {
gob.Register(&color{})
gob.Register(new(tdecoration))
var str strand
gob.Register(str)

tmp := struct {
Id string
Hp int
Gengob []byte
}{}
if err := datastore.LoadStruct(&tmp, c); err != nil {
return err
}

b.Id = tmp.Id
b.Hp = tmp.Hp

return gob.NewDecoder(strings.NewReader(string(tmp.Gengob))).Decode(&(b.Genetics))
}
func (b *bio) Save(c chan<- datastore.Property) error {
defer close(c)
gob.Register(&color{})
gob.Register(new(tdecoration))
var str strand
gob.Register(str)

var buf bytes.Buffer
gen := b.Genetics
if err := gob.NewEncoder(&buf).Encode(&gen); err != nil {
log.Println(err)
return err
}
dp := []datastore.Property{
{Name: "Id", Value: b.Id},
{Name: "Hp", Value: int64(b.Hp)},
{Name: "Gengob", Value: buf.Bytes(), NoIndex: true},
}
for _, p := range dp {
c <- p
}
return nil
}

附加信息:在我填充数据存储区之前不存在此行为在 stop() 中调用 datastore.RunInTransaction()

最佳答案

使用 RegisterName() 在 init() 函数中注册所有类型.从商店中删除所有现有数据,您应该一切顺利。

每次构建应用程序时,App Engine 都会为主包生成一个经过修饰的名称。 Register() 生成的名称包括这个损坏的包名称。任何用错位名称编码的 gob 只能使用相同的应用程序版本读取。如果您通过修改代码导致应用程序重新构建,则该应用程序将无法解码之前存储的 gobs。

关于google-app-engine - 采空区 : interface is only registered on Encode but not on Decode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32417541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com