无法在非接口值上键入开关

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 试图从列表中删除对象但无法在不可变值上使用变异成员:是一个“让”常量

Jquery if复选框是否已选中Bootstrap开关

Swift 2在协议扩展中使用变异函数时出错“无法在不可变值上使用变异成员:'self'是不可变的

电脑无法正常开机

无法在非 XCode Swift 项目中执行“快速测试”