确定 Golang 中函数返回的接口 {} 值的类型

问题描述 投票:0回答:1

我有一个从枚举返回值的函数。枚举定义如下:

type DataType int64

const (
    INT DataType = iota
    FLOAT
    STRING
    BOOL
    CHAR
    VOID
    ERROR
    BREAK
    CONTINUE
)

    func (l *TSwiftVisitor) VisitWhileInstr(ctx *parser.WhileInstrContext) interface{} {        
    if condExpression.ValType == BOOL {             
        condResult := condExpression.asBool()       
        for condResult {            
            for _, currentInstr := range ctx.InstrList().AllInstr() {
                execResult := l.Visit(currentInstr)
                fmt.Printf("TYPE -> %T\n", execResult) // Prints exec.DataType (the type)
                fmt.Printf("VALUE -> %v\n", execResult) // Prints 5 (the enum value)
                if execResult == BREAK { // This never executes
                    fmt.Println("Es break")
                    return VOID
                } else { // This executes
                    fmt.Println("Es otra mierda")
                }
            }           
            condResult = l.Visit(ctx.Expr()).(*Expression).asBool()
        }       
    } else {
        return ERROR
    }
    return VOID
}

Visit方法的签名如下

Visit(tree antlr.ParseTree) interface{}

调用该方法后,我收到一个 DataType 类型的值,并在以下几行中打印该类型和返回值。

fmt.Printf("TYPE -> %T\n", execResult) // Prints exec.DataType (the type)
fmt.Printf("VALUE -> %v\n", execResult) // Prints 5 (the enum value)

输出如下:

TYPE -> exec.DataType                   
VALUE -> 5 

到目前为止,一切都很好,但是我需要进行比较,这就是我遇到的问题,那就是我对 Golang 不太了解。我有以下内容:

if execResult == BREAK { // This never executes
    fmt.Println("It's a break")
    return VOID
} else { // This executes
    fmt.Println("It's another thing")
}

这就是我不知道如何继续验证返回类型的地方,如果我尝试以下几行,我永远不会执行我想要的代码,在本例中是返回 VOID。我的问题是如何比较返回类型以根据结果执行特定操作。我也尝试过以下方法:

switch execResult.(type) {
    case DataType:
        if execResult.(DataType) == BREAK {

            return execResult
        }
}

在这种情况下,开关内的情况也不满足。我的问题基本上是如何确定从函数调用返回的接口 {} 值的类型。

go casting type-conversion typechecking go-reflect
1个回答
0
投票

我认为@Charlie Tumahai 是对的:问题是价值观不匹配。我在 Go Playground 上尝试了一个小示例,它的工作原理与我们预期的一样:如果从

DataType
返回
Visit
,则与
DataType
的比较可以为真。

返回的类型必须是类型

DataType
Visit2
方法证明了这一点:它返回一个
int64
,它永远不会等于
BREAK

Go 编程语言规范中的比较运算符

对此进行了介绍

如果类型 X 具有可比性且 X 实现 T,则非接口类型 X 的值 x 和接口类型 T 的值 t 可以进行比较。如果 t 的动态类型与 X 相同且 t 的动态值等于 x,则它们相等.

package main

import "fmt"

type DataType int64

const (
    INT DataType = iota
    BREAK
    CONTINUE
)

func Visit() interface{} { return BREAK }
func Visit2() interface{} {return int64(BREAK) }

func main() {
    for _, x := range []interface{}{Visit(), Visit2()} {
        fmt.Printf("x = %v, T(x) = %T : ", x, x)
        if x == BREAK {
            fmt.Println("x is BREAK")
        } else {
            fmt.Println("Cannot identify x")
        }
    }

    // Output:
    // x = 1, T(x) = main.DataType : x is BREAK
    // x = 1, T(x) = int64 : Cannot identify x
}
© www.soinside.com 2019 - 2024. All rights reserved.