interface {} 값의 "실제"유형을 결정하는 방법은 무엇입니까?
interface{}
유형 사용에 대한 좋은 리소스를 찾지 못했습니다 . 예를 들면
package main
import "fmt"
func weirdFunc(i int) interface{} {
if i == 0 {
return "zero"
}
return i
}
func main() {
var i = 5
var w = weirdFunc(5)
// this example works!
if tmp, ok := w.(int); ok {
i += tmp
}
fmt.Println("i =", i)
}
Go의 사용에 대한 좋은 소개를 알고 interface{}
있습니까?
구체적인 질문 :
- w의 "실제"유형을 어떻게 얻습니까?
- 유형의 문자열 표현을 얻는 방법이 있습니까?
- 값을 변환하기 위해 유형의 문자열 표현을 사용하는 방법이 있습니까?
귀하의 예가 작동합니다. 다음은 단순화 된 버전입니다.
package main
import "fmt"
func weird(i int) interface{} {
if i < 0 {
return "negative"
}
return i
}
func main() {
var i = 42
if w, ok := weird(7).(int); ok {
i += w
}
if w, ok := weird(-100).(int); ok {
i += w
}
fmt.Println("i =", i)
}
Output:
i = 49
유형 어설 션을 사용합니다 .
유형 스위치를 수행 할 수도 있습니다.
switch v := myInterface.(type) {
case int:
// v is an int here, so e.g. v + 1 is possible.
fmt.Printf("Integer: %v", v)
case float64:
// v is a float64 here, so e.g. v + 1.0 is possible.
fmt.Printf("Float64: %v", v)
case string:
// v is a string here, so e.g. v + " Yeah!" is possible.
fmt.Printf("String: %v", v)
default:
// And here I'm feeling dumb. ;)
fmt.Printf("I don't know, ask stackoverflow.")
}
리플렉션 ( reflect.TypeOf()
)을 사용 하여 무언가의 유형을 가져올 수 있으며, 그것이 제공하는 값 ( Type
)에는 String
인쇄 할 수 있는 문자열 표현 ( 메서드)이 있습니다.
Here is an example of decoding a generic map using both switch and reflection, so if you don't match the type, use reflection to figure it out and then add the type in next time.
var data map[string]interface {}
...
for k, v := range data {
fmt.Printf("pair:%s\t%s\n", k, v)
switch t := v.(type) {
case int:
fmt.Printf("Integer: %v\n", t)
case float64:
fmt.Printf("Float64: %v\n", t)
case string:
fmt.Printf("String: %v\n", t)
case bool:
fmt.Printf("Bool: %v\n", t)
case []interface {}:
for i,n := range t {
fmt.Printf("Item: %v= %v\n", i, n)
}
default:
var r = reflect.TypeOf(t)
fmt.Printf("Other:%v\n", r)
}
}
Type switches can also be used with reflection stuff:
var str = "hello!"
var obj = reflect.ValueOf(&str)
switch obj.Elem().Interface().(type) {
case string:
log.Println("obj contains a pointer to a string")
default:
log.Println("obj contains something else")
}
I'm going to offer up a way to return a boolean based on passing an argument of a reflection Kinds to a local type receiver (because I couldn't find anything like this).
First, we declare our anonymous type of type reflect.Value:
type AnonymousType reflect.Value
Then we add a builder for our local type AnonymousType which can take in any potential type (as an interface):
func ToAnonymousType(obj interface{}) AnonymousType {
return AnonymousType(reflect.ValueOf(obj))
}
Then we add a function for our AnonymousType struct which asserts against a reflect.Kind:
func (a AnonymousType) IsA(typeToAssert reflect.Kind) bool {
return typeToAssert == reflect.Value(a).Kind()
}
This allows us to call the following:
var f float64 = 3.4
anon := ToAnonymousType(f)
if anon.IsA(reflect.String) {
fmt.Println("Its A String!")
} else if anon.IsA(reflect.Float32) {
fmt.Println("Its A Float32!")
} else if anon.IsA(reflect.Float64) {
fmt.Println("Its A Float64!")
} else {
fmt.Println("Failed")
}
Can see a longer, working version here:https://play.golang.org/p/EIAp0z62B7
There are multiple ways to get a string representation of a type. Switches can also be used with user types:
var user interface{}
user = User{name: "Eugene"}
// .(type) can only be used inside a switch
switch v := user.(type) {
case int:
// Built-in types are possible (int, float64, string, etc.)
fmt.Printf("Integer: %v", v)
case User:
// User defined types work as well
fmt.Printf("It's a user: %s\n", user.(User).name)
}
// You can use reflection to get *reflect.rtype
userType := reflect.TypeOf(user)
fmt.Printf("%+v\n", userType)
// You can also use %T to get a string value
fmt.Printf("%T", user)
// You can even get it into a string
userTypeAsString := fmt.Sprintf("%T", user)
if userTypeAsString == "main.User" {
fmt.Printf("\nIt's definitely a user")
}
Link to a playground: https://play.golang.org/p/VDeNDUd9uK6
참고URL : https://stackoverflow.com/questions/6372474/how-to-determine-an-interface-values-real-type
'Programming' 카테고리의 다른 글
중복 AssemblyVersion 특성 (0) | 2020.08.15 |
---|---|
CSS 레이블 너비가 적용되지 않음 (0) | 2020.08.15 |
v120 용 빌드 도구 (플랫폼 도구 세트 = 'v120')를 찾을 수 없습니다. (0) | 2020.08.15 |
C #에서 HTML 소스를 다운로드하려면 어떻게해야합니까? (0) | 2020.08.15 |
C #에서 HTML 소스를 다운로드하려면 어떻게해야합니까? (0) | 2020.08.15 |