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

類似の種類に応じて、さまざまなオプションを持っているかもしれません。あなたの構造に応じて、埋め込まれた構造体

を使用して

、あなたが埋め込まれた構造体を使用することができるかもしれません。

type NormalResult struct { 
    Name string 
    Value int 
} 

をそしてAdminResultが同じ性質を共有するが、ちょうどそれら(ユーザーIDなど)のさらにいくつかを追加した場合、あなたはこのようなAdminResultにNormalResultを埋め込むために選択することができます:

のはNormalResultは次のように定義されているとしましょう
type AdminResult struct { 
    *NormalResult 
    UserId int64 
} 

その後も同様AdminResultに昇格されますNormalResultするためのメソッドを宣言することができます。

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

編集
とは、いや、あなたが示唆したように移動して、条件付きのタイプを持ってすることはできません。変数は1つの型にしかなりません。NormalResultAdminResultまたはinterface{}

+0

'doSomething'を構造体の実装に移すことは良い考えです。もう1つの選択肢は、結果のタイプを抽象化するためにインターフェースを使用することでしたが、私はこのタイプがより好きです。また、誰がこれをコメントなしで投票しますか? – nemo

+2

はい、最初に私はインターフェイスの抽象化を使用して考えたが、埋め込んであなただけのNormalResult'との両方の構造体は、それを実装しているだろう 'のためのインタフェースを実装する必要があります。だからそれはまだ選択肢です。 – ANisus

5

いいえ、この方法ではありません。静的に型付けされ、コンパイル時に型情報を知る必要があります。あなたは何ができるか

はAdminResultとNormalResult満足両方のいくつかのタイプのインターフェースとしてresultを宣言しています。実行時にタイプアサーションを使用して、結果のタイプを判断することができます。あなたの結果タイプがどのように見えるかに依存

(Goはブロックスコープですので、あなたはまた、ブロックの場合の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