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
'programing' 카테고리의 다른 글
버튼을 클릭 할 때 사용자를 리디렉션하려면 어떻게합니까? (0) | 2021.01.17 |
---|---|
SVN 커밋 실패 : 디렉터리가 오래되었습니다. (0) | 2021.01.17 |
Tomcat의 PermGen 공간 오류 (0) | 2021.01.17 |
다른 테이블 값을 기반으로하는 MySQL 업데이트 테이블 (0) | 2021.01.17 |
내 애플리케이션에 AsyncTask 또는 IntentService를 사용해야합니까? (0) | 2021.01.17 |