【问题标题】:Conditional variable declaration in golang?golang中的条件变量声明?
【发布时间】:2013-10-10 03:05:12
【问题描述】:

在 Golang 中可以做这样的条件变量类型声明吗?

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

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

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

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

谢谢!

【问题讨论】:

  • 这取决于您的结果类型是什么样的。能举个例子吗?
  • 这似乎没有意义。你能举一个真实的例子吗?
  • 看起来像代码味道:尝试思考您的问题以及如何更简洁地设计解决方案;您当前的方法很容易导致难以阅读和/或容易出错的代码。

标签: go


【解决方案1】:

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

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

(您还必须在 if 块之外声明 result,因为 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)

}

【讨论】:

  • 就我个人而言,我会使用@ANisus 建议的版本,因为您不需要解压接口并进行类型断言等等。
  • @nemo,我也是,但如果 OP 出于某种原因确实需要使用不同的类型,这将是一种方法。
  • fmt.Println("你好,游乐场", r.Result())
【解决方案2】:

根据何种相似性,您可能有不同的选择。

使用嵌入式结构

根据您的结构,您也许可以使用嵌入式结构。假设 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 中使用条件类型。变量只能是一种类型,NormalResultAdminResultinterface{}

【讨论】:

  • doSomething 移至结构的实现是一个好主意。另一种选择是使用接口来抽象结果类型,但我更喜欢这个。另外,谁投了反对票,没有评论?
  • 是的,首先我想到了使用接口抽象,但是通过嵌入,您只需实现NormalResult 的接口,两个结构都将实现它。所以它仍然是一个选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多