2013-10-09 49 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