首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go错误: gob:类型sync.Mutex没有导出字段

Go错误: gob:类型sync.Mutex没有导出字段
EN

Stack Overflow用户
提问于 2018-05-30 02:31:44
回答 1查看 3.6K关注 0票数 2

如果结构具有导出的sync.Mutex,则无法将其保存为gob,这是我遇到的问题。如果我使互斥不可导出(通过不大写它),一切似乎都能正常工作。我很想了解为什么会出现这种情况,并确保不存在其他问题,因为它是一个未导出的sync.Mutex

我看到谷歌上有几个关于sync.RWMutex相关问题的点击量,但没有人能真正解释为什么会出现这种情况。

代码语言:javascript
复制
package main

import (
    "sync"
    "encoding/gob"
    "os"
    "fmt"
)

func writeGob(filePath string, object interface{}) error {
    file, err := os.Create(filePath)
    defer file.Close()

    if err != nil {
        return err
    }

    encoder := gob.NewEncoder(file)
    err = encoder.Encode(object)
    return err
}

type Dog struct {
    Name string
    GobMux sync.Mutex
}

func main() {
    d := &Dog{Name: "Fido"}
    err := writeGob("./gob", d)
    fmt.Printf("Error: %v\n", err)
}

输出:

错误: gob:类型sync.Mutex没有导出字段

EN

回答 1

Stack Overflow用户

发布于 2019-05-21 19:50:57

Gob编码

如果我使互斥不可导出(通过不大写它),一切似乎都能正常工作。我很想知道这是为什么。

作为塞里西,这里有一个公开发行,但简而言之,如果您试图对没有导出字段的结构(例如互斥)进行编码,通常是一个编程错误。

不过,有一些方法可以解决这个特殊的问题。

您可以将互斥锁设置为私有,并将锁/解锁包装在一个公共函数中,而不是深入到结构中来操作互斥锁。例如。

代码语言:javascript
复制
func (d *Dog) SetName(name string) {
    d.GobMux.Lock()
    d.Name = name
    d.GobMux.Unlock()
}

您还可以包装类型并取出互斥对象:

代码语言:javascript
复制
type Dog struct {
    Name string
}

type DogWrapper struct {
    Dog *Dog
    GobMux sync.Mutex
}

这是相当麻烦的,如果你有许多小的结构,但对于较少的更复杂的结构,这可能是可以的。

最后,解决这个问题的“正确”方法是编写自己的GobEncode/Decode例程。stdlib中有一些稀疏的示例,如time.GobEncode,但通常这似乎是一项相当多的工作。

一般穆特克斯

...and确保未导出的sync.Mutex没有其他问题。

Mutexe与Go运行时的进程内存和调度程序紧密耦合。它们帮助Go运行时决定允许哪些goroutines读取或写入特定的内存部分,并决定何时可以调度这些goroutines (例如,等待互斥锁解锁的大猩猩将在未锁定互斥锁之前不会被调度)。

如果使用gob将数据结构复制到另一个进程,则收件人进程的运行时与发送Gob的进程具有完全不同的内部状态,因此不能逻辑地传输互斥对象。将互斥体复制到另一个进程有点像在火星上使用地球GPS坐标。他们只是不相配。

当我从一个gob中读取一个Dog对象时,它看起来就像一个互斥对象被保存到一个gob时,不管它的状态如何,它都是解锁的。这是我可以信赖的行为吗?

正如Mutex文档声明的那样,“Mutex的零值是一个未锁定的互斥体。”所以是的,你可以依靠这种行为。

其他编码器

在我看来,尽管gob存在于stdlib中,但它并没有得到太多的关注,因为还有许多其他成熟的编码选项可用。如果gob不能满足您的需要,那么还有许多其他选项可用-- JSON、Cap、net/rpc等,它们的不同特性可能更适合您。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50595570

复制
相关文章

相似问题

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