programing

Go 언어에서 런타임에 변수 유형을 확인하는 방법

coolbiz 2021. 1. 17. 11:02
반응형

Go 언어에서 런타임에 변수 유형을 확인하는 방법


이렇게 선언 된 C 함수가 거의 없습니다.

CURLcode curl_wrapper_easy_setopt_long(CURL* curl, CURLoption option, long param);
CURLcode curl_wrapper_easy_setopt_str(CURL* curl, CURLoption option, char* param);

나는 이것들을 하나의 Go 함수로 노출하고 싶습니다.

func (e *Easy)SetOption(option Option, param interface{})

그래서 런타임에 매개 변수 유형 을 확인할 수 있어야 합니다. 어떻게하면 좋을까요? (이 경우 좋은 방법이 아니라면)


여기에서 유형 어설 션을 참조하십시오.

http://golang.org/ref/spec#Type_assertions

나는 현명한 유형 (문자열, uint64) 등 만 주장하고 가능한 한 느슨하게 유지하여 마지막으로 네이티브 유형으로의 변환을 수행합니다.


Go는 이것에 전용 스위치의 특별한 형태를 가지고있는 것 같습니다 (이것은 type switch 라고 합니다 ) :

func (e *Easy)SetOption(option Option, param interface{}) {

    switch v := param.(type) { 
    default:
        fmt.Printf("unexpected type %T", v)
    case uint64:
        e.code = Code(C.curl_wrapper_easy_setopt_long(e.curl, C.CURLoption(option), C.long(v)))
    case string:
        e.code = Code(C.curl_wrapper_easy_setopt_str(e.curl, C.CURLoption(option), C.CString(v)))
    } 
}

@Darius의 대답은 가장 관용적이며 아마도 더 성능이 좋은 방법입니다. 한 가지 제한 사항은 검사중인 유형이 유형이어야한다는 것입니다 interface{}. 구체적인 유형을 사용하면 실패합니다.

구체적인 유형을 포함하여 런타임에 무언가 유형을 결정하는 또 다른 방법은 Go reflect패키지 를 사용하는 것 입니다. TypeOf(x).Kind()함께 연결 하면 http://golang.org/pkg/reflect/#Kind 유형 reflect.Kind값을 얻을 수 있습니다 uint.

그런 다음 다음과 같이 스위치 블록 외부의 유형을 확인할 수 있습니다.

import (
    "fmt"
    "reflect"
)

// ....

x := 42
y := float32(43.3)
z := "hello"

xt := reflect.TypeOf(x).Kind()
yt := reflect.TypeOf(y).Kind()
zt := reflect.TypeOf(z).Kind()

fmt.Printf("%T: %s\n", xt, xt)
fmt.Printf("%T: %s\n", yt, yt)
fmt.Printf("%T: %s\n", zt, zt)

if xt == reflect.Int {
    println(">> x is int")
}
if yt == reflect.Float32 {
    println(">> y is float32")
}
if zt == reflect.String {
    println(">> z is string")
}

출력되는 내용 :

reflect.Kind: int
reflect.Kind: float32
reflect.Kind: string
>> x is int
>> y is float32
>> z is string

다시 말하지만 이것은 아마도 선호되는 방법은 아니지만 대체 옵션을 아는 것이 좋습니다.


quux00의 대답은 기본 유형 비교에 대해서만 알려줍니다.

정의한 유형을 비교해야하는 경우 reflect.TypeOf(xxx). 대신 reflect.TypeOf(xxx).Kind().

유형에는 두 가지 범주가 있습니다.

  • 직접 유형 (직접 정의한 유형)
  • 기본 유형 (int, float64, struct, ...)

다음은 전체 예입니다.

type MyFloat float64
type Vertex struct {
    X, Y float64
}

type EmptyInterface interface {}

type Abser interface {
    Abs() float64
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func (f MyFloat) Abs() float64 {
    return math.Abs(float64(f))
}

var ia, ib Abser
ia = Vertex{1, 2}
ib = MyFloat(1)
fmt.Println(reflect.TypeOf(ia))
fmt.Println(reflect.TypeOf(ia).Kind())
fmt.Println(reflect.TypeOf(ib))
fmt.Println(reflect.TypeOf(ib).Kind())

if reflect.TypeOf(ia) != reflect.TypeOf(ib) {
    fmt.Println("Not equal typeOf")
}
if reflect.TypeOf(ia).Kind() != reflect.TypeOf(ib).Kind() {
    fmt.Println("Not equal kind")
}

ib = Vertex{3, 4}
if reflect.TypeOf(ia) == reflect.TypeOf(ib) {
    fmt.Println("Equal typeOf")
}
if reflect.TypeOf(ia).Kind() == reflect.TypeOf(ib).Kind() {
    fmt.Println("Equal kind")
}

출력은 다음과 같습니다.

main.Vertex
struct
main.MyFloat
float64
Not equal typeOf
Not equal kind
Equal typeOf
Equal kind

보시다시피, reflect.TypeOf(xxx)사용하려는 직접 유형을 reflect.TypeOf(xxx).Kind()반환하고 기본 유형 반환합니다.


여기에 결론이 있습니다. 기본 유형과 비교하려면 reflect.TypeOf(xxx).Kind(); 자체 정의 유형과 비교해야하는 경우 reflect.TypeOf(xxx).

if reflect.TypeOf(ia) == reflect.TypeOf(Vertex{}) {
    fmt.Println("self-defined")
} else if reflect.TypeOf(ia).Kind() == reflect.Float64 {
    fmt.Println("basic types")
}

뭐가 잘못 됐어

func (e *Easy)SetStringOption(option Option, param string)
func (e *Easy)SetLongOption(option Option, param long)

등등?

참조 URL : https://stackoverflow.com/questions/6996704/how-to-check-variable-type-at-runtime-in-go-language

반응형