17

是否可以在 Golang 中进行这样的条件变量类型声明?

if isAdmin {
  var result NormalResult
} else {
  var result AdminResult
}

// do something to &result
doSomething(&result)

func doSomething(interface{}) {
  // something
}

以上不起作用,但想法是 normalResult 和 adminResults 是非常相似的结构,我将如何去做呢?

谢谢!

4

2 回答 2

8

不,不是这种方式。Go 是静态类型的,需要在编译时知道类型信息。

您可以做的是result将 AdminResult 和 NormalResult 都满足的某种类型的接口声明为接口。然后,您可以在运行时使用类型断言来确定它是哪种类型的结果。

(您还必须result在 if 块之外声明,因为 Go 是块作用域)

type NormalResult struct {
    Value int
}

func (r NormalResult) Result() int {
    return r.Value
}

type AdminResult struct {
    Value int
}

func (r AdminResult) Result() int {
    return r.Value
}

type Resulter interface {
    Result() int
}

func main() {
    isAdmin := true
    var r Resulter

    if isAdmin {
        r = AdminResult{2}
    } else {
        r = NormalResult{1}
    }

    fmt.Println("Hello, playground", r)

}
于 2013-10-09T18:52:06.707 回答
7

根据什么样的相似性,您可能有不同的选择。

使用嵌入式结构

根据您的结构,您可能可以使用嵌入式结构。假设 NormalResult 的定义如下:

type NormalResult struct {
    Name  string
    Value int
}

如果 AdminResult 共享相同的属性但只是添加了一些属性(如 UserId),您可以选择将 NormalResult 嵌入到 AdminResult 中,如下所示:

type AdminResult struct {
    *NormalResult
    UserId int64
}

然后,您还可以声明NormalResult将提升为 AdminResult 的方法:

func (r *NormalResult) doSomething() {
    // Doing something
}

编辑
而且,不,Go 中不可能像您建议的那样具有条件类型。一个变量只能是一种类型,be NormalResultitAdminResultinterface{}

于 2013-10-09T18:47:52.103 回答