jjzjj

go - 本地图的键是结构时 Marshal/unMarshal 的问题

coder 2024-07-11 原文

我定义了一个名为 Student 的结构和一个名为 score 的映射。 数据结构如下图:

type Student struct {
    CountryID int
    RegionID  int
    Name      string
}

stu := Student{111, 222, "Tom"}
score := make(map[Student]int64)
score[stu] = 100

我正在使用 json.Marshal 将分数编码到 json 中,但我无法使用 json.Unmarshal 来解码此 json。下面是我的代码。我正在使用函数 GetMarshableObject 将 struct Student 转换为可编码的字符串。 谁能告诉我如何处理这个 json 以将其解码回 map 分数。

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "reflect"
)

type Student struct {
    CountryID int
    RegionID  int
    Name      string
}

func GetMarshableObject(src interface{}) interface{} {
    t := reflect.TypeOf(src)
    v := reflect.ValueOf(src)
    kind := t.Kind()
    var result reflect.Value
    switch kind {
    case reflect.Map:
        //Find the map layer count
        layer := 0
        cur := t.Elem()
        for reflect.Map == cur.Kind() {
            layer++
            cur = cur.Elem()
        }
        result = reflect.MakeMap(reflect.MapOf(reflect.TypeOf("a"), cur))
        for layer > 0 {
            result = reflect.MakeMap(reflect.MapOf(reflect.TypeOf("a"), result.Type()))
            layer--
        }
        keys := v.MapKeys()
        for _, k := range keys {
            value := reflect.ValueOf(GetMarshableObject(v.MapIndex(k).Interface()))
            if value.Type() != result.Type().Elem() {
                result = reflect.MakeMap(reflect.MapOf(reflect.TypeOf("a"), value.Type()))
            }
            result.SetMapIndex(reflect.ValueOf(fmt.Sprintf("%v", k)), reflect.ValueOf(GetMarshableObject(v.MapIndex(k).Interface())))
        }
    default:
        result = v
    }
    return result.Interface()
}

func main() {
    stu := Student{111, 222, "Tom"}
    score := make(map[Student]int64)
    score[stu] = 100

    b, err := json.Marshal(GetMarshableObject(score))
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stdout.Write(b) //{"{111 222 Tom}":100}

    scoreBak := make(map[Student]int64)
    if err = json.Unmarshal(b, &scoreBak); nil != err {
        fmt.Println("error: %v", err) // get error here: cannot unmarshal object into Go value of type map[main.Student]int64
    }
}

最佳答案

来自docs :

The map's key type must either be a string, an integer type, or implement encoding.TextMarshaler.

func (s Student) MarshalText() (text []byte, err error) {
    type noMethod Student
    return json.Marshal(noMethod(s))
}

func (s *Student) UnmarshalText(text []byte) error {
    type noMethod Student
    return json.Unmarshal(text, (*noMethod)(s))
}

例如,我使用 encoding/json 将 Student 值转换为 json 对象键,但这不是必需的,您可以选择自己的格式。

https://play.golang.org/p/4BgZn4Y37Ww

关于go - 本地图的键是结构时 Marshal/unMarshal 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55335296/

有关go - 本地图的键是结构时 Marshal/unMarshal 的问题的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  6. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  7. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  8. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  9. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐