【问题标题】:Mysterious type assertion failure?神秘类型断言失败?
【发布时间】:2015-07-27 21:32:18
【问题描述】:

什么情况下可以这样编码:

        v, ok := value.(int64)
        if !ok  {
            panic("NOPE "+reflect.TypeOf(value).Kind().String())
        } else {
            fmt.Printf("VAL: %d\n",v)
        }

使用消息panic: NOPE int64产生恐慌?

这是一个错误还是我缺少的数字类型有一些基本的东西?

【问题讨论】:

  • 如果有帮助,该值是一个 int64 通过 interface{} 函数参数传递到此代码所在的函数中。(这是一个很长的函数,并且在其他地方复制它的简单尝试已经失败...)
  • 我运行了你的代码,它运行得非常好。问题不在这个sn-p之外。见play.golang.org/p/NCHCVqz13C
  • 正如我所说,我无法创建 MCVE - 它只是在 /in situ/ 失败,当然可以自行运行(否则我们会遇到真正的麻烦!)。如果您愿意,“此 sn-p 之外的哪些可能问题可能导致此问题?” - 我根本看不出我所描述的行为可以合法地发生,不管我在其他地方“搞砸了”什么......但我对“合法”的理解可能是不正确的。
  • 哦,我可以轻松地重新创建它,方法是执行 type T int64 之类的操作并让 value 引用 T。打印reflect.TypeOf(value) 会给你带来什么?
  • 那么,这就解决了。我会发布它作为答案。

标签: reflection types go


【解决方案1】:

如果您对数字类型使用类型声明,就会发生这种情况。如果你这样做:

type T int64 

...

var value interface{} = T(1)

并将其放入您的代码中,您将得到完全相同的错误。但如果你不检查种类,而是检查类型,你会看到这里发生了什么:

v, ok := value.(int64)
if !ok {
    panic("NOPE " + reflect.TypeOf(value).String())
} else {
    fmt.Printf("VAL: %d\n", v)
}

产生消息:

panic: NOPE main.T

T 的 kind 是 int64,但 value 不是 int64。

【讨论】:

  • 太棒了,TYVM。但是,如何在不“知道”有问题的(编译时符号)类型的情况下将其转换回 int64?嗯,这应该是一个后续问题可能......将发布。
  • @BadZen 你可以用反射做到这一点:var i int64 = reflect.ValueOf(value).Int()
  • 那么你的开关是那种吗?那么每个案例可以有多个值。例如case int, int16, int32, int64 - Value.Int() 对它们都一样。
  • 是的。只是注意到我需要拆分uint 和朋友的案例并在那里使用Value.Uint(),否则可能会砍一点。
  • @Not_a_Golfer “类型别名”:Go 中唯一的别名类型是内置的 byterune 类型(int8int32 的别名)。通过type declaration 完成的任何操作都会使用它自己的identity 创建一个新类型,而不是任何东西的别名。
猜你喜欢
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多