首页 > 其他分享 >Go踩坑:interface{}判断nil

Go踩坑:interface{}判断nil

时间:2024-07-18 19:09:55浏览次数:7  
标签:string nil point value interface Go type

问题背景

在实习的一次真实程序开发中,我编写了一个函数,其处理一个接口类型(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
}

标签:string,nil,point,value,interface,Go,type
From: https://www.cnblogs.com/shui00cc/p/18310263

相关文章

  • 管理索引mongo
    列出数据库的所有索引db.getCollectionNames().forEach(function(collection){indexes=db[collection].getIndexes();print("Indexesfor"+collection+":");printjson(indexes);});列出特定类型的索引//Thefollowingfindsallhashedindex......
  • mongo索引类型
    要创建单字段索引,请使用以下原型:db.<collection>.createIndex({<field>:<sortOrder>})复合索引要创建复合索引,请使用下列 db.collection.createIndex()方法: db.<collection>.createIndex({<field1>:<sortOrder>,<field2>:<sortOrder&......
  • 强烈推荐:18.3k star,推荐一款简单易用的HTTP请求流量录制回放工具:Goreplay
    在软件开发和测试过程中,我们经常需要对应用程序的网络请求进行录制和回放,以便进行性能分析、压力测试或者模拟复杂的网络环境。今天,我要向大家推荐一款简单易用的HTTP请求流量录制回放工具:Goreplay。1、简介Goreplay是一款用Go语言编写的HTTP请求流量录制回放工具。它可......
  • mongo并发与锁
    MongoDB使用哪种类型的锁定?除了用于读取的共享(S)锁定模式和用于写入操作的独占(X)锁定模式之外,意图共享(IS)和意图独占(IX)模式表示使用更细粒度的锁来读取或写入资源的意图。按一定粒度锁定时,所有更高级别都使用意向锁例如,当锁定一个集合进行写入(使用模式X)时,相应的......
  • 吐血整理如何在Google Earth Engine上写循环 五个代码实例详细拆解
    在这里同步一篇本人的原创文章。原文发布于2023年发布在知乎专栏,转移过来时略有修改。全文共计3万余字,希望帮助到GEE小白快速进阶。引言这篇文章主要解答GEE中.map()和.iterate()函数的用法。首先解答一个疑问,为什么需要自己写循环?确实,GEE为各种数据类型提供了无数常用的内置......
  • Golang的KisFlow流式计算框架概述
    1.1为什么需要KisFlow一些大型toB企业级的项目,需要大量的业务数据,多数的数据需要流式实时计算的能力,但是很多公司还不足以承担一个数仓类似,Flink+Hadoop/HBase等等。但是业务数据的实时计算需求依然存在,所以大多数的企业依然会让业务工程师来消化这些业务数据计算的工作......
  • 可视化—gojs 超多超实用经验分享(四)
    目录41.监听连线拖拽结束后的事件42.监听画布的修改事件43.监听节点被del删除后回调事件(用于实现调用接口做一些真实的删除操作)44.监听节点鼠标移入移出事件,hover后显示特定元素45.监听树图实现鼠标点击节点本身展开或收起子节点的功能,而不是点击另外的按钮46.监听文本块编......
  • 程序员常用Mac工具、Idea插件以及Google插件
    1、Typora工具官网地址:https://typoraio.cn/推荐指数:★★★★★作为程序员,Markdown工具肯定是必不可少的,可以用来记录一些技术文档,推荐Typora,整个风格比较简约,自带的样式不太好看,推荐插件typora-theme-pie添加图片注释,不超过140字(可选)2、Termius工具官方地址:https:/......
  • 你是如何解决go语言框架 gin跨域问题 的 ?
    我们在做前后端分离的项目,时常会听到跨域问题。经常看到有人的文章标题写着:前端支持跨域,但显然也只是个噱头而已。跨域的概念,本人才疏学浅,就不多说了。大家有兴趣可以搜搜相关的介绍。今天就聊一聊在go的web框架gin里面怎么解决跨域问题,以及在实践过程中踩的坑。大概已经抄了m......
  • public interface View接口和public interface ViewResolver接口介绍
    在SpringMVC中,publicinterfaceView和publicinterfaceViewResolver是两个相互关联但功能不同的接口。它们共同在视图解析和渲染过程中发挥作用,但各自承担的责任不同。View接口View接口定义了如何渲染一个特定的视图。它通常包含一个render方法,该方法接受一个Model......