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

Min*_*gyu 20 interface type-conversion go

我使用以下虚拟代码玩类型断言,我得到错误:

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

有谁知道这是什么意思?

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 := &Number{1}
    switch v := n.(type) {
    case Stringer:
        fmt.Println("Stringer:", v)
    default:
        fmt.Println("Unknown")
    }
}
Run Code Online (Sandbox Code Playgroud)

http://play.golang.org/p/Ti4FG0m1mc

Min*_*gyu 36

我想出了答案,这是投ninterface{}类型断言之前:

switch v := interface{}(n).(type)
Run Code Online (Sandbox Code Playgroud)

  • 没有理由在现实生活中使用此代码,因为任何非接口变量(即,`n`)在您的源代码中已经具有一个无法更改的已知类型。例如,如果它被声明为一个int,你就知道它无论如何都是一个int。 (4认同)
  • 我很想知道为什么这会得到如此多的赞成?人们肯定正在寻找用例 (2认同)
  • 是的,所以简短的答案是,如果 Go 知道输入的类型,那么对于类型转换/断言来说,这是错误的输入。因此,您必须将输入强制转换为接口{},例如在外部函数中或像此处所示的那样。 (2认同)

det*_*000 24

类型开关需要一个内省的界面.如果你传递一个已知类型的值,它就会爆炸.如果你创建一个接受接口作为参数的函数,它将工作:

func typeSwitch(tst interface{}) {
    switch v := tst.(type) {
        case Stringer:
           fmt.Println("Stringer:", v)
        default:
           fmt.Println("Unknown")
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅http://play.golang.org/p/QNyf0eG71_的完整代码以及接口http://golang.org/doc/effective_go.html#interfaces上的golang文档.