碰到一个switch case疑惑

windy_ · 2018-04-17 18:09:33 · 1442 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2018-04-17 18:09:33 的主题,其中的信息可能已经有所发展或是发生改变。

我有一个判空函数

func IsEmpty(val interface{}) bool {
    if val != nil {
        switch v := val.(type) {
        case bool:
            return false
        case string:
            return v == ""
        case int64, int8, int32, int, int16, float64, float32, uint64, uint8, uint32, uint, uint16:
            return v == 0
        case time.Time:
            return v.IsZero()
        case []interface{}:
            return len(v) == 0
        case []byte:
            return len(v) == 0
        case []int64:
            return len(v) == 0
        ....
        }

    }
    return true
}

case数组类型时,觉得代码很恶心

于是我像下面这样写

func IsEmpty(val interface{}) bool {
    if val != nil {
        switch v := val.(type) {
        case bool:
            return false
        case string:
            return v == ""
        case int64, int8, int32, int, int16, float64, float32, uint64, uint8, uint32, uint, uint16:
            return v == 0
        case time.Time:
            return v.IsZero()
        case []interface{}, []byte, []int64....:
            return len(v) == 0
        }

    }
    return true
}

但是代码报错了,len() 参数错误。

这个地方比较疑惑,求大佬解释一下,或者有什么更好的实现


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1442 次点击  
加入收藏 微博
10 回复  |  直到 2018-04-23 11:36:40
terender
terender · #1 · 7年之前

你后面的v都应该是 val 啊, v是val的类型,val才是要判断的变量本身。

windy_
windy_ · #2 · 7年之前
terenderterender #1 回复

你后面的v都应该是 val 啊, v是val的类型,val才是要判断的变量本身。

麻烦了解一下switch - type 的语法

windzhu0514
windzhu0514 · #3 · 7年之前

推荐使用反射 v := reflect.ValueOf(x) switch v.Kind() { case reflect.Bool: fmt.Printf("bool: %v\n", v.Bool()) case reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64: fmt.Printf("int: %v\n", v.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64: fmt.Printf("int: %v\n", v.Uint()) case reflect.Float32, reflect.Float64: fmt.Printf("float: %v\n", v.Float()) case reflect.String: fmt.Printf("string: %v\n", v.String()) case reflect.Slice: fmt.Printf("slice: len=%d, %v\n", v.Len(), v.Interface()) case reflect.Map: fmt.Printf("map: %v\n", v.Interface()) case reflect.Chan: fmt.Printf("chan %v\n", v.Interface()) default: fmt.Println(x) }

windzhu0514
windzhu0514 · #4 · 7年之前

推荐使用反射

v := reflect.ValueOf(x)
switch v.Kind() {
case reflect.Bool:
    fmt.Printf("bool: %v\n", v.Bool())
case reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64:
    fmt.Printf("int: %v\n", v.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64:
    fmt.Printf("int: %v\n", v.Uint())
case reflect.Float32, reflect.Float64:
    fmt.Printf("float: %v\n", v.Float())
case reflect.String:
    fmt.Printf("string: %v\n", v.String())
case reflect.Slice:
    fmt.Printf("slice: len=%d, %v\n", v.Len(), v.Interface())
case reflect.Map:
    fmt.Printf("map: %v\n", v.Interface())
case reflect.Chan:
    fmt.Printf("chan %v\n", v.Interface())
default:
    fmt.Println(x)
}
momaek
momaek · #5 · 7年之前

推荐使用 4楼 的方法

windy_
windy_ · #6 · 7年之前
windzhu0514windzhu0514 #4 回复

推荐使用反射 ```go v := reflect.ValueOf(x) switch v.Kind() { case reflect.Bool: fmt.Printf("bool: %v\n", v.Bool()) case reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64: fmt.Printf("int: %v\n", v.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64: fmt.Printf("int: %v\n", v.Uint()) case reflect.Float32, reflect.Float64: fmt.Printf("float: %v\n", v.Float()) case reflect.String: fmt.Printf("string: %v\n", v.String()) case reflect.Slice: fmt.Printf("slice: len=%d, %v\n", v.Len(), v.Interface()) case reflect.Map: fmt.Printf("map: %v\n", v.Interface()) case reflect.Chan: fmt.Printf("chan %v\n", v.Interface()) default: fmt.Println(x) } ```

非常感谢

alex_023
alex_023 · #7 · 7年之前

使用反射,会使用堆,性能下降20-50倍

windy_
windy_ · #8 · 7年之前
alex_023alex_023 #7 回复

使用反射,会使用堆,性能下降20-50倍

写法精简一点。。。

dong-hao
dong-hao · #9 · 7年之前

原因在于,使用 switch type 时,如果 case 上有多个类型的话,v 会被认为是 interface{} 类型的,对 interface{} 取 len 当然就不对了。

windy_
windy_ · #10 · 7年之前
dong-haodong-hao #9 回复

原因在于,使用 switch type 时,如果 case 上有多个类型的话,v 会被认为是 interface{} 类型的,对 interface{} 取 len 当然就不对了。

多谢,后来看错误提示明白了

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传