无法在非接口值上键入开关
Posted
技术标签:
【中文标题】无法在非接口值上键入开关【英文标题】:Cannot type switch on non-interface value 【发布时间】:2014-06-04 00:45:25 【问题描述】:我正在使用以下虚拟代码进行类型断言,但出现错误:
不能在非接口值上键入开关
有人知道这是什么意思吗?
package main
import "fmt"
import "strconv"
type Stringer interface
String() string
type Number struct
v int
func (number *Number) String() string
return strconv.Itoa(number.v)
func main()
n := &Number1
switch v := n.(type)
case Stringer:
fmt.Println("Stringer:", v)
default:
fmt.Println("Unknown")
http://play.golang.org/p/Ti4FG0m1mc
【问题讨论】:
但是对已知类型进行类型断言有什么意义呢? @newacct 是的,在生产代码中,如果类型已知,您当然不会进行类型断言。本练习的重点是理解类型断言。 【参考方案1】:有两种类型转换
基本数据类型之间的转换。为此,我们可以使用直接铸造
i := 48
str := string(i)
但是使用 value.(type) 的类型转换是用于类层次结构之间的转换,(例如,我们希望从接口获取特定实现的位置)。否则,我们会得到上述错误。
【讨论】:
【参考方案2】:Go 中没有类型转换。您正在进行类型转换。
【讨论】:
【参考方案3】:我想出了答案,就是在类型断言之前将n
转换为interface
:
switch v := interface(n).(type)
【讨论】:
没有理由在现实生活中使用此代码,因为任何非接口变量(即n
)在您的源代码中已经具有无法更改的已知类型。例如,如果它被声明为一个 int,那么无论如何你都知道它是一个 int。
我很想知道为什么这会得到如此多的支持?当然人们正在寻找一个用例
由于某种原因,我有一个指向结构的指针数组,当我操作数组(添加项)时,当我尝试键入 assert 时,它变成了不是接口。转换为 interface 修复了“左侧的非接口类型”错误。
我的案例是用地图解析 yaml 文件
是的,所以简短的回答是,如果 Go 知道输入的类型,那就是类型转换/断言的错误输入。因此,您必须将输入转换为接口,您可以在外部函数中执行此操作,或者像此处显示的那样。【参考方案4】:
类型开关需要一个接口来进行自省。如果您将已知类型的值传递给它,它就会爆炸。如果您创建一个接受接口作为参数的函数,它将起作用:
func typeSwitch(tst interface)
switch v := tst.(type)
case Stringer:
fmt.Println("Stringer:", v)
default:
fmt.Println("Unknown")
在此处查看完整代码 http://play.golang.org/p/QNyf0eG71_ 以及关于接口 http://golang.org/doc/effective_go.html#interfaces 的 golang 文档。
【讨论】:
谢谢,@dethtron5000。我缺少的是在type assertion
之前需要显式转换为 interface
。
这个答案对我帮助很大。我正在通过结构类型的开关解决一些更复杂的情况,但这将我推向了正确的方向。谢谢你,兄弟。登录只是为了告诉你)
这个答案对我帮助很大。我正在通过结构类型的开关解决一些更复杂的情况,但这将我推向了正确的方向。谢谢你,兄弟。登录只是为了告诉你)以上是关于无法在非接口值上键入开关的主要内容,如果未能解决你的问题,请参考以下文章
Vue 警告我无法在未定义、null 或原始值上设置反应属性:null
SwiftUI 试图从列表中删除对象但无法在不可变值上使用变异成员:是一个“让”常量