Check for nil and nil interface in Go

后端 未结 4 1301
生来不讨喜
生来不讨喜 2020-12-07 18:48

Currently I\'m using this helper function to check for nil and nil interfaces

func isNil(a interface{}) bool {
  defer func() { recover() }()
  return a == n         


        
4条回答
  •  死守一世寂寞
    2020-12-07 19:17

    This is the interface definition for this exmaple solution:

    package checker
    
    import (
        "errors"
    
        "github.com/rs/zerolog"
    )
    
    var (
        // ErrNilChecker returned if Check invoked on a nil checker
        ErrNilChecker = errors.New("attempted Check with nil Checker")
    
        // ErrNilLogger returned if the Check function is provide a nil logger
        ErrNilLogger = errors.New("nil logger provided for Check")
    )
    
    // Checker defines the interface
    type Checker interface {
        Check(logger *zerolog.Logger) error
    }
    

    One of our Checker implementations supports aggregation of Checkers. But testing uncovered the same issue as this thread. This solution uses the reflect package if the simple nil check fails, leveraging the reflect.Value type to resolve the question.

    // AggregateChecker implements the Checker interface, and
    //  supports reporting the results of applying each checker
    type AggregateChecker struct {
        checkers []Checker
    }
    
    func (ac *AggregateChecker) Add(aChecker Checker) error {
        if aChecker == nil {
            return ErrNilChecker
        }
    
        // It is possible the interface is a typed nil value
        // E.g. checker := (&MyChecker)(nil)
        t := reflect.TypeOf(aChecker)
        if reflect.ValueOf(aChecker) == reflect.Zero(t) {
            return ErrNilChecker
        }
    
        ac.checkers = append(ac.checkers, aChecker)
        return nil
    }
    

提交回复
热议问题