游戏人生
About Me
  • 你好
  • Math
    • Number
      • Float IEEE754对确定性的影响
      • Pairing Function及其用途
    • Vector and Matrix
      • TRS基础概念
      • LossyScale深入分析
    • Quatenion
      • FromToRotation实现细节
    • Lerp and Curve
      • Slerp球形插值
      • Bezier Curve为什么重要
      • Interpolation和Extrapolation实现细节
  • Programming
    • C#
      • 学习资料
      • C# struct灵魂拷问
      • CIL的世界:call和callvirt
      • .NET装箱拆箱机制
      • .NET垃圾回收机制
    • Go
      • 基础特性
      • 如何正确的判空interface
      • 如何用interface模拟多态
      • 如何定制json序列化
      • 如何安全在循环中删除元素
      • 如何安全关闭channel
      • 如何集成c++库(cgo+swig)
      • 如何性能测试(benchmark, pprof)
    • Lua
      • 基础特性
  • General Game Development
    • Game Engine
      • 学习资料
      • 关于游戏引擎的认知
    • Networking
      • 帧同步
      • 状态同步
      • 物理同步
    • Physics
      • PhysX基本概念
      • PhysX增加Scale支持
      • PhysX场景查询
      • PhysX碰撞检测
      • PhysX刚体动力学
      • PhysX角色控制器
      • PhysX接入项目工程
      • 物理同步
      • 物理破坏
    • Design Pattern
      • 常用设计模式
      • MVP 架构模式
      • ECS 架构模式
  • Unity
    • Runtime
      • Unity拥抱CoreCLR
      • 浅析Mono内存管理
    • UGUI
      • 浅析UGUI渲染机制
      • 浅析UGUI文本优化
      • 介绍若干UGUI实用技巧
    • Resource Management
      • 浅析Unity堆内存的分类和管理方式
      • 深入Unity资源
      • 深入Unity序列化
      • 深入Assetbundle机制
    • Async
      • 深入Unity协程
      • 介绍若干Unity协程实用技巧
      • 异步动作队列
    • Hot Reload
      • Unity+Xlua
      • Xlua Examples学习(一)
      • Xlua Examples学习(二)
    • Editor Extension
    • Performance
      • 浅析Unity Profiler
      • 介绍一个Overdraw分析工具
  • Platform
    • WebGL
  • Real-world Project
    • Souce Engine
    • DOOM3 BFG
Powered by GitBook
On this page
  • Check Type Assertion
  • Check interface{}
  • Check Return Value
  1. Programming
  2. Go

如何正确的判空interface

涉及interface时,由于interface对象里包含了类型指针和真实对象指针,所以只对interface对只判断nil是不够的。下面列举三种容易踩坑的情况以及正确的判空方法。最后一个最隐蔽也最容易出错:当不得以要返回一个interface返回值时,要格外注意判空方法!

Check Type Assertion

知道具体类型,转换成具体类型判断:

a, ok := obj.(*SomeType)
if ok && a!= nil {
    // really ok
}

Check interface{}

不知道具体类型,只能从interface对象判断真实对象是否有效:

func isNil(a interface{}) bool {
    defer func() {
        recover()
    }()
    return a == nil || reflect.ValueOf(a).IsNil()
}

Check Return Value

函数返回一个interface的情况本质上不复杂,但很容易被调用方忽视。总结概括为:要么转成具体类型判断,要么使用反射reflect.ValueOf(a).IsNil()判断。

下面是具体例子。

package main
import (
    "fmt"
    "reflect"
)
    
type IMatchTeam interface {
    GetTeamIndex() uint32
}

type MatchTeam struct {
}

func (this *MatchTeam) GetTeamIndex() uint32 {
    return 0
}
    
// this function return an interface
func ChangeTeam() IMatchTeam {
    var t *MatchTeam
    return t // "t" is nil, but Go wraps this "typed nil" into a interface object, which is not nil itself
}
    
func main() {
    res := ChangeTeam() // res now is an interface object

    if res != nil {
        fmt.Println("This is true!")
            
        ti, ok := res.(IMatchTeam)
        if ok {
            fmt.Println("This is true! Suprise!")
        }
        if ti != nil {
            fmt.Println("This is true! Suprise!!")
        }
        if !reflect.ValueOf(ti).IsNil() { // the only right way to check underlying value of ti
            fmt.Println("Never happen")
        }
    
        t, ok2 := res.(*MatchTeam)
        if ok2 {
            fmt.Println("This is true! Suprise!!!")
        }
        if t != nil {
            fmt.Println("Never happen")
        }
    }
}
Previous基础特性Next如何用interface模拟多态

Last updated 20 days ago