随笔 - 16  文章 - 0  评论 - 1  阅读 - 7537

Go踩坑:interface{}判断nil

问题背景

在实习的一次真实程序开发中,我编写了一个函数,其处理一个接口类型(interface{})的参数,根据其类型返回一个字符串。
在传入的参数为nil时,我希望通过判断,返回空字符串。看看我的大致代码:

func main() {
  	var p *int64
	fmt.Println(defaultValueFn(p)) // p未赋值,我希望返回空字符串
}

func defaultValueFn(point interface{}) string {
    if point == nil {
        return ""
    }
    var value string
    switch v := point.(type) {
    case *int64:
        value = strconv.FormatInt(*v, 10)
    case *time.Time:
        value = (*v).Format(time.RFC1123)
    case *string:
        value = *v
    default:
        value = ""
    }
    return value
}

然而我运行时报错:panic: runtime error: invalid memory address or nil pointer dereference

问题分析

我们看src/runtime/runtime2.go源码中如何定义interface:

type eface struct {
	_type *_type
	data  unsafe.Pointer
}

eface结构体表示不含 method 的 interface 结构,有一个字段_type *_type表示类型,有一个字段data unsafe.Pointer指向了这个interface代表的具体数据
问题就是,当我们传入一个空值但type非空的interface时,==nil判断将返回flase
因此在下面的*v解包操作会失败

问题解决

分析完问题的产生原因后,这里提供我的一个解决方法,在类型断言成功后,进一步检查指针type是否为 nil

func defaultValueFn(point interface{}) string {
    if point == nil {
        return ""
    }
    var value string
    switch v := point.(type) {
    case *int64:
        if v != nil { // 这里进一步判断
            value = strconv.FormatInt(*v, 10)
        } else {
            value = ""
        }
    case *time.Time:
        if v != nil {
            value = (*v).Format(time.RFC1123)
        } else {
            value = ""
        }
    case *string:
        if v != nil {
            value = *v
        } else {
            value = ""
        }
    default:
        value = ""
    }
    return value
}
posted on   shui00cc  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示