2014-09-02 14 views
1

다른 객체 유형을 많이 처리하는 일부 일반 함수를 만들려고합니다. 일부 유형은 기본 객체를 작성한 편리한 하위 유형을 포함합니다.GoLang의 임베디드 메서드에 액세스

'값 인터페이스 {}'에 BaseObject가 포함되어 있는지 테스트하는 방법이나 그 중 하나를 호출하는 방법을 알아낼 수 없습니다. ToString() ... 반환해야하는 [TestObject] 없습니다 [BaseObject]

package Test 

import(
    "fmt" 
    "reflect" 
) 

func main() { 
    Value:=TestObject{} 
    TestFunction(Value) 
} 

//Generic function 
func TestFunction(Value interface{}){ 

    // Does value contain BaseObject? reflect.TypeOf(Value).Containes...Implements?? 
    //Convert to BaseObject? BO:=Value.(BaseObject) 
    // If it does, call BO.ToString() 
    //fmt.println(BO.ToString()) 
} 

//Base Object 
type BaseObject struct { 
} 
func (this *HCObject) ToString() string { 
    return "[BaseObject]" 
} 

//Test Object 
type TestObject struct{ 
    BaseObject 
} 
func (this *TestObject) ToString() string { 
    return "[TestObject]" 
} 
+0

'interface {} '에 대한 자세한 내용은 http://stackoverflow.com/a/23148998/6309를 참조하십시오. – VonC

+2

Go에서 "클래식"OOP를 수행하려는 경우 실망하게됩니다. Go-like 솔루션을 찾을 수 없습니까? – Volker

+3

Go에서 클래스 스타일의 객체 지향 코드를 작성하려고하지 않는 것이 좋습니다. Go에는 클래스, 서브 클래스, 상속 등이 없습니다. – JimB

답변

3

첫째, 점 몇 :

  • play.golang.org에서 코드 예제를 작업에 대한 링크를 제공하는 것이 좋습니다.
  • 항상 코드를 작성하십시오.
  • ToStringString이어야합니다. fmt.Stringer 인터페이스를 참조하십시오.
  • 다른 사람들이 지적했듯이, Go에서 C++의 Java를 작성하려고하면 뒤에서 통증 로그가 끝납니다.

이렇게 말하면, this은 많은 것을 제외하고 원하는 것을 수행하는 코드의 실행 가능한 예입니다.

func TestFunction(v interface{}) { 
    fmt.Println(reflect.ValueOf(v).FieldByName("BaseObject").MethodByName("String").Call(nil)[0].String()) 
} 

이 코드는 (당신이 정말이 그것을 필요로 할 때에 만 당신이해야 뭔가 임) reflect 패키지를 사용합니다. 이 예제를 가지고 놀고 reflect을 파헤 치면 Go를 계속하는 것이 가치가 있는지 여부를 알 수 있습니다.

+0

이것은 해결책과 같습니다. 나는 여전히 내 자신의 코드로 작동하도록 노력하고 있지만 play.golang.org에서 작동하는 데모입니다. 고맙습니다. –

+0

@GordonTruslove :이 경우 리플렉션을 사용할 필요가 없습니다 (가능하면 피해야합니다). 인터페이스 [예] (http://play.golang.org/p/VyoUW18NGU)를 사용하면이 작업을 완전히 수행 할 수 있습니다. 메소드 세트와 일치하는 포인터를 전달하는지 확인해야합니다. – JimB

+0

그 예가 최상의 솔루션입니다. 나는 그것을 구현하려고 할 것입니다. 모든 추가 인터페이스 메소드를 구현하기위한 약간의 추가 작업을 의미합니다. 감사. –

2

당신 interface{}에 없다 "삽입"을 수행. 인터페이스 자체는 메소드 세트를 가지고 있으며, 어떤 값과 타입 정보를 가지고있다.

Type Assertion을 사용하여 인터페이스에서 값을 추출합니다.

bo, ok := value.(BaseObject) 
if ok { 
    fmt.Println(bo) 
} 

개 이상의 유형을 확인하려면

, 당신은 유형 스위치를 사용

테스트 기능은 같은 것을 포함 할 수 있습니다. 귀하의 경우 TestObject와 BaseObject는 완전히 다른 유형입니다. TestObject는 BaseObject가 아닙니다. 당신이 포함 된 유형의 방법의 상위 집합을 갖는 삽입 유형으로, 두 가지 유형을 구분해야하는 경우

switch bo := value.(type) { 
case TestObject: 
    fmt.Println("TestObject", bo) 
case BaseObject: 
    fmt.Println("BaseObject", bo) 
} 

, 당신이 필요로하는 방법과 일치하는 인터페이스를 정의합니다. 이 경우 Sub에서

type Base interface { 
    MethodA() 
} 

type Sub interface { 
    MethodA() 
    MethodB() 
} 

또한 Base 인터페이스를 충족의 Sub 인터페이스를 충족하는 아무것도하는 Base입니다. 모든

+0

전 두 가지를 시도했지만 어느 것도 작동하지 않았습니다. 값 (TestObject) 및 대문자 TestObject : 만 작동합니다. –

+0

실행 가능한 예제를 만들어보십시오. 형식 어설 션에서 오류가 발생하면 '패닉 : 인터페이스 변환 : 인터페이스는 main.TbaseObject가 아니라 main.BaseObject'입니다. 다시, * Go에 상속이 없다. type-> embedded-type is-a 관계는 없습니다. 포함은 위임의 편리한 형태 일 뿐이고 인터페이스를 사용하여 다형성을 구현합니다. – JimB