在Go语言中,在类型切换语句中检查”struct”类型会导致语法错误。

huangapple go评论87阅读模式
英文:

Checking for "struct" type in a type switch statement in Go results in syntax error

问题

在学习Go语言中的类型切换语句时,我尝试按如下方式检查"struct"类型:

package main

import "fmt"

func moo(i interface{}) {
    switch v := i.(type) {
    case string:
        fmt.Printf("Byte length of %T: %v \n", v, len(v))
    case int:
        fmt.Printf("Two times this %T: %v \n", v, v)
    case bool:
        fmt.Printf("Truthy guy is %v \n", v)
    case struct:
        fmt.Printf("Life is complicated with %v \n", v)
    default:
        fmt.Println("don't know")
    }
}

func main() {
    moo(21)
    moo("hello")
    moo(true)
}

然而,这导致了与struct类型相关的语法错误(如果移除检查struct类型的case语句,则不会出现此错误):

tmp/sandbox396439025/main.go:13: syntax error: unexpected :, expecting {
tmp/sandbox396439025/main.go:14: syntax error: unexpected (, expecting semicolon, newline, or }
tmp/sandbox396439025/main.go:17: syntax error: unexpected semicolon or newline, expecting :
tmp/sandbox396439025/main.go:20: syntax error: unexpected main, expecting (
tmp/sandbox396439025/main.go:21: syntax error: unexpected moo

是否有原因导致无法在此处检查struct类型?请注意,func moo()正在检查类型为interface{}i,这是一个空接口,理论上应该由每种类型(包括struct)实现。

Go Playground完整代码:

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

英文:

While learning about the type switch statement in Go, I tried to check for the "struct" type as follows:

package main

import "fmt"

func moo(i interface{}) {
	switch v := i.(type) {
	case string:
		fmt.Printf("Byte length of %T: %v \n", v, len(v))
	case int:
		fmt.Printf("Two times this %T: %v \n", v, v)
	case bool:
		fmt.Printf("Truthy guy is %v \n", v)
	case struct:
		fmt.Printf("Life is complicated with %v \n", v)
	default:
		fmt.Println("don't know")
	}
}

func main() {
	moo(21)
	moo("hello")
	moo(true)
}

However, this resulted in a syntax error related to the struct type (not seen if the case statement checking for the struct type is removed:

tmp/sandbox396439025/main.go:13: syntax error: unexpected :, expecting {
tmp/sandbox396439025/main.go:14: syntax error: unexpected (, expecting semicolon, newline, or }
tmp/sandbox396439025/main.go:17: syntax error: unexpected semicolon or newline, expecting :
tmp/sandbox396439025/main.go:20: syntax error: unexpected main, expecting (
tmp/sandbox396439025/main.go:21: syntax error: unexpected moo

Is there a reason why the struct type cannot be checked for here? Note that the func moo() is checking for i of type interface{}, an empty interface which should supposedly be implemented by every type, including struct

Go Playground full code:

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

答案1

得分: 4

struct不是一种类型,而是一个关键字。

这是一个示例类型(使用类型字面量给出):

struct { i int }

或者是Point类型:

type Point struct { X, Y int }

所以以下代码是有效的:

switch v := i.(type) {
case struct{ i int }:
    fmt.Printf("Life is complicated with %v \n", v)
case Point:
    fmt.Printf("Point, X = %d, Y = %d \n", v.X, v.Y)
}

你可以将struct看作是一种类型的"种类",可以使用反射进行检查,例如:

var p Point
if reflect.TypeOf(p).Kind() == reflect.Struct {
    fmt.Println("It's a struct")
}

Go Playground上尝试一下。

英文:

struct is not a type, it's a keyword.

This is a type for example (given using a type literal):

struct { i int }

Or Point:

type Point struct { X, Y int }

So the following code works:

switch v := i.(type) {
case struct{ i int }:
	fmt.Printf("Life is complicated with %v \n", v)
case Point:
	fmt.Printf("Point, X = %d, Y = %d \n", v.X, v.Y)
}

You may look at struct as being a kind of type, which you can check using reflection, for example:

var p Point
if reflect.TypeOf(p).Kind() == reflect.Struct {
    fmt.Println("It's a struct")
}

Try it on the Go Playground.

huangapple
  • 本文由 发表于 2017年2月28日 16:12:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/42503378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定