第三十七:类型断言

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
}

主要区别:

  1. 字符串string 类型

  2. 数组 :固定长度,如 [3]int

  3. 切片 :可变长度,如 []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
}
相关推荐
涅小槃3 分钟前
Carla仿真学习笔记(版本0.9.16)
开发语言·python·ros·carla
wujialaoer5 分钟前
常用软件阿里源地址
开发语言·python
小O的算法实验室6 分钟前
2023年CIE SCI2区TOP,ACO+PSO+A*:一种用于 AUV 多任务路径规划的双层混合算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
Ro Jace9 分钟前
A Real-Time Cross Correlator for Neurophysiological Research
人工智能·python·算法
沐知全栈开发18 分钟前
SVG 文本:深入解析与高效应用
开发语言
张丶大帅22 分钟前
【走进Golang】
开发语言·后端·golang
Sheep Shaun24 分钟前
深入理解红黑树:从概念到完整C++实现详解
java·开发语言·数据结构·c++·b树·算法
Dave.B24 分钟前
:vtkBooleanOperationPolyDataFilter 布尔运算全解析
算法·vtk
楼田莉子26 分钟前
CMake学习:入门及其下载配置
开发语言·c++·vscode·后端·学习
易晨 微盛·企微管家29 分钟前
2025企业微信AI智能机器人实战指南:3步实现客服自动化
大数据·人工智能·算法