2013-10-09 51 views
7

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

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

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

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

以上不工作,但这些想法是normalResult和adminResults是非常相似的结构,我怎么会去这样做?

谢谢!

+0

这取决于你的结果类型是什么样子。你能举个例子吗? – nemo

+0

这似乎没有道理。你能举一个真实世界的例子吗? –

+1

看起来像一个代码异味:尝试思考你的问题,以及如何更清晰地设计解决方案;您目前的方法很容易导致难以阅读和/或容易出错的代码。 –

回答

4

根据不同类型的相似性,您可能有不同的选项。

使用嵌入式结构

根据您的结构,那么您可以使用嵌入式结构。比方说,NormalResult的定义是这样的:

type NormalResult struct { 
    Name string 
    Value int 
} 

如果AdminResult共享相同的属性,但只是增加了一些更多的人(如用户ID),你可以选择嵌入NormalResult到AdminResult这样的:

type AdminResult struct { 
    *NormalResult 
    UserId int64 
} 

那么你也可以申报NormalResult方法将被晋升为AdminResult还有:

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

编辑
而且,不,根据您的建议,无法在Go中添加条件类型。一个变量只能是一种类型,无论是NormalResult,AdminResultinterface{}

+0

将'doSomething'移动到struct的实现是个好主意。另一种选择是使用接口来抽象结果类型,但我更喜欢这个。此外,谁没有发表评论呢? – nemo

+2

是的,首先我想到了使用接口抽象,但嵌入你只需要实现'NormalResult'的接口,并且这两个结构都会实现它。所以它仍然是一个选择。 – ANisus

5

不,不是这样。进行静态类型化时,需要在编译时了解类型信息。

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

(你也要申报result外,如果块的,因为围棋是块作用域)

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) 

} 
+0

就我个人而言,我会使用@ANisus版本,因为您不需要解压界面并输入断言等等。 – nemo

+1

@nemo,就像我一样,但如果OP由于某种原因确实需要使用不同的类型,这将是一种方法。 – JimB