Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate if struct variable is empty or not

Tags:

go

First of all, look at the following code snippet:

package main

import (
    "fmt"
)

func main() {

    var para1 struct {
        email, addr string
    }

    para1.email = "[email protected]"

    if para1 != nil {
        fmt.Println(para1)
    }

}

When I compile this code, I've got the compiler error:

./struct_func.go:15: cannot convert nil to type struct { email string; addr string }

How can I validate if my struct variable, if nil or not? Or I have to validate of property like

if para1.email != nil {
    fmt.Println(para1)
}
like image 928
softshipper Avatar asked Aug 17 '14 12:08

softshipper


3 Answers

You can compare the struct to its zero value. You can test the string for its zero (empty) value "" or test for string length zero. For example,

package main

import (
    "fmt"
)

func main() {
    var para1 struct {
        email, addr string
    }
    para1Zero := para1
    para1.email = "[email protected]"
    if para1 != para1Zero {
        fmt.Println(para1)
    }
    if para1.email != "" {
        fmt.Println(para1.email)
    }
    if len(para1.email) != 0 {
        fmt.Println(para1.email)
    }
}

Output:

{[email protected] }
[email protected]
[email protected]

The Go Programming Language Specification

The zero value

When memory is allocated to store a value, either through a declaration or a call of make or new, and no explicit initialization is provided, the memory is given a default initialization. Each element of such a value is set to the zero value for its type: false for booleans, 0 for integers, 0.0 for floats, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.

like image 107
peterSO Avatar answered Oct 26 '22 15:10

peterSO


I know this has been quiet for a while, but a nice reusable way to validate that a struct is empty is to use the "reflect" built-in. It allows you to compare against an empty copy of your struct. Here is a version of your code using an isEmpty function based on reflect.

package main

import (
    "fmt"
    "reflect"
)

func isEmpty(object interface{}) bool {
    //First check normal definitions of empty
    if object == nil {
        return true
    } else if object == "" {
        return true
    } else if object == false {
        return true
    }

    //Then see if it's a struct
    if reflect.ValueOf(object).Kind() == reflect.Struct {
        // and create an empty copy of the struct object to compare against
        empty := reflect.New(reflect.TypeOf(object)).Elem().Interface()
        if reflect.DeepEqual(object, empty) {
            return true
        }
    }
    return false
}

func main() {

    var para1 struct {
        email, addr string
    }

    para1.email = "[email protected]"

    if isEmpty(para1) {
        fmt.Println("It's empty")
    } else {
        fmt.Println(para1)
    }
}

http://play.golang.org/p/geqHKMSWzp

like image 21
vastlysuperiorman Avatar answered Oct 26 '22 17:10

vastlysuperiorman


var para1 struct {
    email, addr string
}

After this line, para1 is a struct value containing 2 empty strings as you can see here.

only slices, maps, channels, pointers and functions can be nil. Therefore comparing para1 to nil does not make sense and the compiler is complaining about that.

Admittedly the error message could be better.

If you want to know if para1 is empty you should give its type a name and declare a method on it:

type Parameter struct {
    email, addr string
}

func (p Parameter) Empty() bool {
    return (p.email != "" && p.addr != "")
}
like image 26
thwd Avatar answered Oct 26 '22 15:10

thwd