Go
package main
import (
"fmt"
"go/types"
)
func doSomething(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("Integer:", v)
case string:
fmt.Println("String:", v)
default:
fmt.Println("Unknown type")
}
}
// 区分字符串、数组、切片
func aa(i interface{}) {
switch v := i.(type) {
case string:
fmt.Println("i is a string:", v)
case int:
fmt.Println("i is an int:", v)
case types.Slice:
fmt.Println("i is a slice:", v)
case types.Array:
fmt.Println("i is an array:", v)
case []string:
fmt.Println("i is a slice of strings:", v)
case []int:
fmt.Println("i is a slice of int:", v)
case []interface{}:
fmt.Println("i is a slice of interface{}:", v)
default:
fmt.Println("i is of a different type")
}
}
func main() {
aa("hello")
aa(123)
aa([]int{1, 2, 3})
aa([]string{"aaa", "bbb", "ccc"})
aa([3]int{4, 5, 6})
aa([]interface{}{1, "a", true})
}
判断是否为切片(不区分元素类型)
Go
func isSlice(value interface{}) bool {
switch value.(type) {
case []interface{}, []string, []int, []float64, []bool:
return true
default:
// 使用反射判断任意切片类型
return reflect.TypeOf(value).Kind() == reflect.Slice
}
}
2. 使用反射(reflect包)
Go
import "reflect"
func checkTypeReflect(value interface{}) {
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.String:
fmt.Println("字符串类型")
case reflect.Slice:
fmt.Println("切片类型")
// 进一步判断切片元素类型
if v.Type().Elem().Kind() == reflect.String {
fmt.Println("元素类型是 string")
} else if v.Type().Elem().Kind() == reflect.Interface {
fmt.Println("元素类型是 interface{}")
}
case reflect.Array:
fmt.Println("数组类型")
default:
fmt.Printf("类型: %v\n", v.Kind())
}
}
3. 判断是否为数组(不是切片)
Go
func isArray(value interface{}) bool {
t := reflect.TypeOf(value)
return t.Kind() == reflect.Array
}
func isSlice(value interface{}) bool {
t := reflect.TypeOf(value)
return t.Kind() == reflect.Slice
}
func isString(value interface{}) bool {
t := reflect.TypeOf(value)
return t.Kind() == reflect.String
}
4. 实用示例函数
Go
import (
"fmt"
"reflect"
)
func GetTypeInfo(value interface{}) (string, string) {
v := reflect.ValueOf(value)
kind := v.Kind()
var typeName string
var elementType string
switch kind {
case reflect.String:
typeName = "string"
case reflect.Slice:
typeName = "slice"
// 获取元素类型
elemType := v.Type().Elem()
elementType = elemType.String()
case reflect.Array:
typeName = "array"
elemType := v.Type().Elem()
elementType = elemType.String()
default:
typeName = kind.String()
}
return typeName, elementType
}
// 使用示例
func main() {
str := "hello"
strSlice := []string{"a", "b"}
intSlice := []int{1, 2}
arr := [3]int{1, 2, 3}
fmt.Println(GetTypeInfo(str)) // string,
fmt.Println(GetTypeInfo(strSlice)) // slice, string
fmt.Println(GetTypeInfo(intSlice)) // slice, int
fmt.Println(GetTypeInfo(arr)) // array, int
}
5. 判断是否为字符串切片(特定类型)
Go
func IsStringSlice(value interface{}) bool {
switch v := value.(type) {
case []string:
return true
default:
// 使用反射检查
rv := reflect.ValueOf(value)
if rv.Kind() != reflect.Slice {
return false
}
return rv.Type().Elem().Kind() == reflect.String
}
}
func IsSliceOfType(value interface{}, elemKind reflect.Kind) bool {
rv := reflect.ValueOf(value)
if rv.Kind() != reflect.Slice {
return false
}
return rv.Type().Elem().Kind() == elemKind
}
主要区别:
-
字符串 :
string类型 -
数组 :固定长度,如
[3]int -
切片 :可变长度,如
[]int、[]string
方法1:使用反射(reflect)
Go
package main
import (
"fmt"
"reflect"
)
func main() {
var s []int = []int{1, 2, 3}
fmt.Println(isSlice(s)) // 输出:true
var n int = 10
fmt.Println(isSlice(n)) // 输出:false
}
func isSlice(x interface{}) bool {
return reflect.TypeOf(x).Kind() == reflect.Slice
}
方法2:使用类型断言
Go
package main
import (
"fmt"
)
func main() {
var s []int = []int{1, 2, 3}
fmt.Println(isSlice(s)) // 输出:true,但这种方式主要用于已知具体类型的情况,不是通用检查是否为切片的最佳方法。
}
// 注意:下面的方法实际上并不适用于通用检查是否为切片,因为你需要知道具体的切片类型。
// 正确的做法应该是使用反射或直接比较类型。
func isSlice(x interface{}) bool {
_, ok := x.([]int) // 这里需要明确知道切片的元素类型。这不是通用方法。
return ok
}
正确的通用方法:使用反射检查任意切片类型
Go
package main
import (
"fmt"
"reflect"
)
func main() {
var s []int = []int{1, 2, 3}
fmt.Println(isAnySlice(s)) // 输出:true
var s2 []string = []string{"a", "b", "c"}
fmt.Println(isAnySlice(s2)) // 输出:true
}
func isAnySlice(x interface{}) bool {
return reflect.TypeOf(x).Kind() == reflect.Slice
}
用reflect包来判断变量是数组还是切片
Go
arr := [5]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}
// 判断数据类型
arrType := reflect.TypeOf(arr)
sliceType := reflect.TypeOf(slice)
// 输出结果
fmt.Println("arrType:", arrType)
//结果为 [5]int
fmt.Println("sliceType:", sliceType)
//结果为 []int
fmt.Println(arrType.Kind())
//结果为 array
fmt.Println(sliceType.Kind())
//结果为slice
}
