草庐IT

Go map 和界面{}

coder 2024-07-13 原文

我对以下go语句的合法性有疑问。为什么我不能直接转换这两种类型?

package main

import (
    "fmt"
)

type xtype interface{}
type ytype map[string]map[string]bool

func main() {
    myvar := map[string]xtype{
        "x": map[string]interface{}{
            "foo": map[string]interface{}{
                "bar": true,
            },
        },
    }
    x := myvar["x"] // x is of type 'xtype'
    fmt.Println(x)  // Prints map[foo:map[bar:true]]
    y := x.(ytype)  // Panic
    fmt.Println(y)  //
}

这段代码可以编译,但是在运行时,你会遇到 panic

紧急:接口(interface)转换:main.xtype 是 map[string]interface {},不是 main.ytype

有人可以解释为什么这是 panic 吗?显然,在这种情况下它们属于同一类型。是否可以在 Go 中进行这种直接转换?

编辑

虽然这是一个人为的例子,但这确实出现在现实世界中。例如,Cloud Firestore 的(Firebase 的一部分)Go 库以 map[string]interface{} 的形式从数据库返回 map ,无论 map 有多深。所以直接转换成目标类型真的很方便

最佳答案

您正在尝试隐式转换嵌套接口(interface),但这行不通。 x类型为 interface{} ,并根据您的结构持有 map[string]interface{} .该映射中包含的接口(interface)每个都包含一个 map[string]interface{}。 ,而那些最终的接口(interface)每个都有一个 bool 值。您无法转换 interface{map[string]interface{}{map[string]interface{}{bool}}map[string]map[string]bool在一次拍摄中,因为这需要展开外部接口(interface)(由 x 持有的接口(interface))、映射中的每个内部接口(interface),然后是每个内部映射中包含 bool 值的每个接口(interface)。由于在每一级映射中可以有多个键,这是一个 O(n) 操作(实际上,更接近于 O(n*m)),并且接口(interface)转换是专门设计的,因此你不能单行 O(n) 转换。

如果你专门解包每一层,并且一次只尝试解包一个接口(interface),它工作得很好。在旁注中,您可以使用 fmt.Printf("%#v", <var>)打印有关变量的显式类型信息。

https://play.golang.org/p/Ng9CE0O34G

package main

import (
    "fmt"
)

type xtype interface{}
type ytype map[string]map[string]bool

func main() {
    myvar := map[string]xtype{
        "x": map[string]interface{}{
            "foo": map[string]interface{}{
                "bar": true,
            },
        },
    }

    x := myvar["x"]        // x is of type 'xtype'
    fmt.Printf("%#v\n", x) // map[string]interface {}{"foo":map[string]interface {}{"bar":true}}

    mid := x.(map[string]interface{})
    fmt.Printf("%#v\n", mid) // map[string]interface {}{"foo":map[string]interface {}{"bar":true}}

    y := make(map[string]map[string]bool)
    for k, v := range mid {
        m := make(map[string]bool)
        for j, u := range v.(map[string]interface{}) {
            m[j] = u.(bool)
        }
        y[k] = m
    }
    fmt.Printf("%#v\n", y) // map[string]map[string]bool{"foo":map[string]bool{"bar":true}}
}

关于Go map 和界面{},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46954314/

有关Go map 和界面{}的更多相关文章

  1. ruby - 如何让我的枚举器接受提要的界面? - 2

    来自docsforRubyv2.5e=[1,2,3].mappe.next#=>1e.feed"a"pe.next#=>2e.feed"b"pe.next#=>3e.feed"c"begine.nextrescueStopIterationp$!.result#=>["a","b","c"]end但是当我通过Enumerator.new创建我的枚举时呢?#anaivereworkoftheaboveenume2=Enumerator.newdo|y|[1,2,3].eachdo|x|y1e2.feed"a"pe2.next#=>2e2.feed"b"pe2.next#=>3e2.fee

  2. 嵌入式学习之QT学习----3 制作简单的QT界面(如:QQ登录界面) - 2

    1、创建一个QT工程newproject—>Application—>QtWidgetsApplication—>choose…(注意不要有中文路径)填写名称(我写的名称为class2)和创建路径(D:\qt\qt_demo\class2)—>填写类名,这里基类要选择“QWidget”,这样一个QT工程就创建好啦。qt的移植性非常强,一套代码我们不用修改太多,直接通用所有的平台。说明:QMainWindow:主窗口类,主窗口具有主菜单栏、工具栏和状态栏,类似于一般的应用程序的主窗口。QWidget:它是所有具有可视界面的基类,选择QWidget创建的界面对各种界面组件都可以支持。QDialog

  3. javascript - 用户界面 - 内联帮助覆盖 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭4年前。Improvethisquestion我有一个客户在寻找类似于Facebook和Google用来突出显示界面变化的类型的内联帮助系统。这是UI模式中的示例:http://ui-patterns.com/users/1/collections/38/entry/5759在推介自定义解决方案之前,我真的需要了解是否有任何现有的库或服务可提供此功能。我在StackOverflow和Google(以及其他网站)上

  4. javascript - jQuery 用户界面 : Uncaught TypeError: Cannot read property 'display' of undefined - 2

    我正在尝试使用jqueryajax获取数据,一切正常,我得到了我想要的,但我无法显示它,因为我收到未捕获的类型错误:无法读取未定义的属性“显示”。这里是代码。有什么想法吗?/**Getthedatafromtheajaxcallanddisplayadialog*/functionCreateDialog(email){//getthedatafromtheajaxcallvarpromise=AjaxSubscribe(email)//ifdataareavailable,showthedialogpromise.success(function(data){//dataisasim

  5. javascript - Angular 用户界面 TinyMCE : How set default settings - 2

    我正在使用angularuitinymce扩展。我想知道如何设置我可以在常规JavaScript中执行的以下设置。tinymce.init({selector:"textarea",height:250,theme:"modern",plugins:["advlistautolinklistslinkimagecharmapprintpreviewhranchorpagebreak","searchreplacewordcountvisualblocksvisualcharscodefullscreen","insertdatetimemedianonbreakingsavetable

  6. javascript - 扩展 TypeScript 的控制台界面 - 2

    我想在window.console全局添加一个对象。importReactotronfrom'reactotron-react-native';window.console.tron=Reactotron;尽管当我这样做时,TypeScript会提示新对象:errorTS2339:Property'tron'doesnotexistontype'Console'.我想扩展控制台界面:interfaceConsoleWithTronextendsConsole{tron:any};不过,我不确定如何将这个新界面分配给我的全局控制台对象?帮助会很棒!谢谢。 最佳

  7. QtUI界面被QProcess阻塞(已解决) - 2

    在Qt开发中经常会使用到一个等待界面,很巧,这周开发就遇到了,思索了半天,还是问问度娘,网上的答案很乱。浅浅记录一下首先我制作了一个按钮,按下按钮的时候会有一个弹窗选择,如果选择“YES”就往下执行等待画面,在等待中我得在Linux下打包指定的文件到指定目录。这里我用的是QProcess来操作。打包用到的命令:tar-czf 路径/文件名.tgz 目标文件现在我们来制作一个简单的UI界面 UI制作Ok,只需要把gif图片Setmovie到QLabel上就行,封装起来随时调用。QMovie*pMovie=newQMovie(":/image/Image/loading.gif");ui->loa

  8. QT+VS开发界面入门(qt界面在VS2022实现自动生成槽函数) - 2

    QT+VS开发入门无论使用QTCreater单独开发,或者使用VS的MFC单独开发,都能通过转到槽函数/双击插件,进行跳转一个插件的响应函数。而习惯了使用VS编程,又想使用QT进行界面开发,那就很有必要看一下这篇文章。关于QT与VS如何联动,请看我的另一篇文章:VS+QT开发环境搭建创建项目先上项目列表:ui_QtWidgetsApplication1.h:包含了UI界面内的参数属性。界面布局,插件位置,槽函数的连接函数等。QtWidgetsApplication1.ui:UI界面,双击打开,会在QTDesigner工具中打开,可以拖拽插件进行界面设计。QtWidgetsApplication

  9. c# - 如何使用 Facebook 应用程序开发界面邀请用户连接到您的应用程序 - 2

    我认为这个问题已经被质疑过了,答案可能就在这里:http://wiki.developers.facebook.com/index.php/Notifications.send但真正的问题是facebook说:Facebook于2010年3月1日停止支持此方法。调用此方法返回错误代码3--未知方法。同时,我找不到任何其他JS-api用于邀请,有人知道我们如何使用JSapi或.netapi邀请用户吗?谢谢。 最佳答案 Application-to-useranduser-to-usernotificationshavebeenremo

  10. javascript - 如何在 angularJS 指令中使用 jQuery 插件(语义用户界面)? - 2

    我在我的项目中使用semantic-ui,pulgin是checkbox有人说如果使用jQ插件,你必须在angular指令中使用它但它不起作用semantic-uiAPI文档中semantic-ui设置的checkbox,你必须将其设置为initcheckbox$('.ui.checkbox').checkbox();我尝试将其更改为这样的Angular:app.html这是angularjs文件中的指令todoApp.directive('todoCheckbox',function(){return{restrict:'A',link:function(scope,elem,att

随机推荐