2013-10-09 18 views
7

È possibile eseguire una dichiarazione del tipo di variabile condizionale come questa in Golang?Dichiarazione variabile condizionale in golang?

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

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

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

È possibile che questo non funziona, ma le idee è che normalResult e adminResults sono le strutture molto simili e come dovrei andare a fare questo?

Grazie!

+0

Questo dipende da ciò che i tipi di risultato simile. Puoi dare degli esempi? – nemo

+0

Questo non sembra avere senso. Puoi dare un esempio del mondo reale? –

+1

Sembra un odore di codice: prova a pensare al tuo problema ea come progettare la soluzione in modo più pulito; il tuo approccio attuale può facilmente portare a un codice difficile da leggere e/o soggetto a errori. –

risposta

4

A seconda del tipo di somiglianze, è possibile che siano disponibili opzioni diverse.

Utilizzando le strutture incorporate

seconda vostra struttura, si potrebbe essere in grado di utilizzare le strutture embedded. Diciamo NormalResult si definisce in questo modo:

type NormalResult struct { 
    Name string 
    Value int 
} 

E se AdminResult condivide le stesse proprietà, ma aggiunge solo un po 'di più di loro (come UserId), è possibile scegliere di incorporare NormalResult nella AdminResult in questo modo:

type AdminResult struct { 
    *NormalResult 
    UserId int64 
} 

Poi si può anche dichiarare metodi per NormalResult che sarà promosso a AdminResult così:

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

Edit
E, no, non è possibile avere tipi condizionali in Go come suggerito. Una variabile può essere di un solo tipo, sia NormalResult, AdminResult o interface{}

+0

Spostare 'doSomething' nell'implementazione della struttura è una buona idea. L'altra opzione sarebbe stata usare le interfacce per astrarre il tipo di risultato, ma mi piace di più questo. Inoltre, chi vota questo senza nessun commento? – nemo

+2

Sì, innanzitutto ho pensato di utilizzare l'astrazione dell'interfaccia, ma con l'incorporamento è sufficiente implementare l'interfaccia per 'NormalResult' e entrambe le strutture l'avranno implementata. Quindi è ancora un'opzione. – ANisus

5

No, non in questo modo. Vai a essere staticamente digitato, ha bisogno di conoscere le informazioni sul tipo al momento della compilazione.

Quello che potresti fare è dichiarare result come un'interfaccia di un tipo che sia AdminResult che NormalResult soddisfano. È quindi possibile utilizzare un tipo di asserzione in fase di esecuzione per decidere quale tipo di risultato è.

(È anche dichiarare result al di fuori dei blocchi, se a causa Go è blocco ambito)

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

Personalmente, vorrei utilizzare la versione di @ANisus suggerita in quanto non è necessario decomprimere l'interfaccia e digitare le asserzioni e così via. – nemo

+1

@nemo, come vorrei, ma se l'OP avesse davvero bisogno di usare un tipo distinto per qualche ragione, questo sarebbe un modo per farlo. – JimB

Problemi correlati