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

(당신은 또한 이동 블록이 범위 때문에 경우 블록의 result 외부를 선언해야한다). 예제를 줄 수 있습니까? – nemo

+0

이것은 이해가되지 않는 것 같습니다. 현실 세계의 예를들 수 있습니까? –

+1

코드 냄새처럼 보입니다 : 문제에 대해 생각하고 솔루션을보다 깔끔하게 디자인하는 방법을 생각해보십시오. 현재의 접근 방식은 쉽게 읽기 어렵고 오류가 발생하기 쉬운 코드로 쉽게 이어질 수 있습니다. –

답변

4

어떤 종류의 유사성에 따라 다른 옵션이있을 수 있습니다. 당신의 구조에 따라 포함 된 구조체

를 사용

, 당신은 포함 된 구조체를 사용할 수 있습니다.

type NormalResult struct { 
    Name string 
    Value int 
} 

을 그리고 AdminResult은 동일한 속성을 공유하지만, 단지 그들 (사용자 아이디 등)의 몇 가지 더 추가하면,이 같은 AdminResult에 NormalResult을 포함하도록 선택할 수 있습니다 :

의이 NormalResult는 다음과 같이 정의되어 있다고 가정 해 봅시다
type AdminResult struct { 
    *NormalResult 
    UserId int64 
} 

그럼 당신은 또한뿐만 아니라 AdminResult로 승격 될 NormalResult 방법을 선언 할 수

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

편집
그리고, 아니요, 제안한대로 Go에 조건부 유형을 포함 할 수 없습니다. 변수는 한 유형일 수 있습니다. NormalResult, AdminResult 또는 interface{}

+0

'doSomething'을 구조체의 구현체로 옮기는 것이 좋습니다. 다른 옵션은 결과 유형을 추상화하기 위해 인터페이스를 사용하는 것이었지만이 방법이 더 좋았습니다. 또한, 누구가 코멘트없이 이것을 투표합니까? – nemo

+2

네, 먼저 인터페이스 추상화를 사용하는 것에 대해 생각했습니다.하지만 포함 시키면 'NormalResult'에 대한 인터페이스 만 구현하면되며 두 구조체 모두 구현할 수 있습니다. 그래서 그것은 여전히 ​​선택 사항입니다. – ANisus

5

아니요. 정적으로 입력하면 컴파일 할 때 유형 정보를 알아야합니다.

당신이 할 수있는 일은 result을 AdminResult와 NormalResult가 만족하는 어떤 유형의 인터페이스로 선언하는 것입니다. 그런 다음 런타임에 형식 어설 션을 사용하여 결과 형식을 결정할 수 있습니다.

은 결과 유형이 어떤 모습인지에 따라 그

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