2017-11-27 1 views
2

런타임시 지정된 함수를 테스트하여 특정 서명과 일치하는지 확인하려고합니다. 이 서명은 특정 구현이 아닌 일부 인터페이스를 준수하는 것으로 충분합니다.스위치로 인터페이스별로 기능을 확인하십시오.

나는 그런 검증을 할 올바른 패턴을 찾을 수없는 것 같습니다. 런타임에 함수의 유형이 구현을 사용하고 있습니다.

함수의 서명을 인터페이스와 어떻게 비교할 수 있습니까?

package main 

import "fmt" 

type myinteface interface{ 
    DoSomething(int) string 
} 

type myfunc func(myinteface) 

type impl struct {} 

func (im *impl) DoSomething(int) string{ 
    return "fsdfsd" 
} 

func do(i interface{}) { 
    switch v := i.(type) { 
    case func(myinteface): 
     fmt.Print("doesn't stop here") 
    case func(impl):  
     fmt.Print("this does work") 
    default: 
     fmt.Printf("I don't know about type %T!\n", v) 
    } 
} 

func test(im impl) {} 

func main() { 
    do(test) 
} 

는 수동 reflect 패키지를 사용하여 인수를 입력 확인 할 수는 playground

+1

당신에게 말하는 것은 완전히 맞습니다. 'test'는'func (myinteface)'가 아닌'func (impl)'이며'func (myinteface)'로 사용할 수 없습니다. – hobbs

+0

나는 그것이 정확한지 알고있다. 그러나'impl '은'myinterface'를 만족 시키므로, 함수가 시그니처에 그 인터페이스의 구현을 가지고 있는지를 알고 싶다. – yarons

+1

@hobbs가 말했던 것과 그 외 : function types Golang에서 (배열과 조각뿐만 아니라) * invariant *입니다. 이 용어로 검색하면 다양한 관련 기사가 많이 나옵니다. – zerkms

답변

2

에 살고 참조하십시오. 다음은 myinteface의 예입니다. 첫 번째 매개 변수 Implements 원하는 인터페이스 여부를 확인합니다. 간결함을 위해 기능에는 오직 하나의 의무적 인 주장 만 있다고 가정합니다. 프로덕션을 위해서는 인수의 수 (주석 처리 된 문자열은 NumIn())와 모든 유형을 주기적으로 검사하는 것이 좋습니다.

func do(i interface{}) { 
    val := reflect.ValueOf(i) 
    typ := val.Type() 
    // numIn := typ.NumIn() 
    arg0 := typ.In(0) 
    modelType := reflect.TypeOf((*myinteface)(nil)).Elem() 
    if arg0.Implements(modelType) { 
     fmt.Println("OK") 
    } else { 
     fmt.Println("not OK") 
    } 
} 

또한 수신기 유형 (값 또는 포인터)에주의하십시오. 예를 들어 여기서 test2 함수 인수는 myinteface을 구현하지만 testimpl 구조체의 포인터 수신기 때문에 발생하지 않습니다.

func test(im impl) {} 

func test2(im *impl) {} 

func main() { 
    do(test) 
    do(test2) 
} 

데모 : 당신이 값 수신기 구조체 정의를 변경하는 경우 https://play.golang.org/p/ZDZKZIh2lW

다음 두 함수의 인수를 구현 : 귀하의 질문에서

type impl struct{} 

func (im impl) DoSomething(int) string { 
    return "fsdfsd" 
} 

https://play.golang.org/p/xvasgBs-_a

0

를가 조금 어렵다 당신이 그 기능에 대해 주장하고 싶은 것을 말하십시오. 나는 네가 필요로하는 것을 생각하는 것을 썼다.

질문에 함수 test은 포인터가 아니기 때문에 myinteface을 구현하는 매개 변수를 사용하지 않았습니다.

멘토링 된 것처럼, 이것을 사용하여 해결하려는 문제에 대한 다른 해결책을 찾아야 할 것입니다.

package main 

import "fmt" 
import "reflect" 

type myinteface interface { 
    DoSomething(int) string 
} 

type myfunc func(myinteface) 

type impl struct{} 

func (im *impl) DoSomething(int) string { 
    return "fsdfsd" 
} 

//Does the function passed as `i` take a type that implements the `myinteface` type as first parameter 
func do(i interface{}) { 
    functionType := reflect.TypeOf(i) 
    if functionType.Kind() != reflect.Func { 
     fmt.Printf("(%s) is not a function", functionType) 
    } 
    ourInterfaceType := reflect.TypeOf((*myinteface)(nil)).Elem() 
    if functionType.In(0).Implements(ourInterfaceType) { 
     fmt.Printf("(%s)'s first paramter implements the `myinteface` interface\n", functionType) 
    } else { 
     fmt.Printf("(%s)'s first paramter does not implement the `myinteface` interface\n", functionType) 
    } 
} 

func test(im *impl) {} 
func test2(im impl) {} 

func main() { 
    do(test) 
    do(test2) 
} 
관련 문제