How to do it...

The following steps cover how to write and run your application:

  1. From your Terminal/console application, create a new directory called ~/projects/go-programming-cookbook/chapter3/nulls.
  2. Navigate to this directory.
  3. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter3/nulls

You should see a file called go.mod that contains the following:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter3/nulls    
  1. Copy tests from ~/projects/go-programming-cookbook-original/chapter3/nulls or use this as an exercise to write some of your own code!
  2. Create a file called base.go with the following content:
        package nulls

import (
"encoding/json"
"fmt"
)

// json that has name but not age
const (
jsonBlob = `{"name": "Aaron"}`
fulljsonBlob = `{"name":"Aaron", "age":0}`
)

// Example is a basic struct with age
// and name fields
type Example struct {
Age int `json:"age,omitempty"`
Name string `json:"name"`
}

// BaseEncoding shows encoding and
// decoding with normal types
func BaseEncoding() error {
e := Example{}

// note that no age = 0 age
if err := json.Unmarshal([]byte(jsonBlob), &e); err != nil
{
return err
}
fmt.Printf("Regular Unmarshal, no age: %+v ", e)

value, err := json.Marshal(&e)
if err != nil {
return err
}
fmt.Println("Regular Marshal, with no age:", string(value))

if err := json.Unmarshal([]byte(fulljsonBlob), &e);
err != nil {
return err
}
fmt.Printf("Regular Unmarshal, with age = 0: %+v ", e)

value, err = json.Marshal(&e)
if err != nil {
return err
}
fmt.Println("Regular Marshal, with age = 0:",
string(value))

return nil
}
  1. Create a file called pointer.go with the following content:
        package nulls

import (
"encoding/json"
"fmt"
)

// ExamplePointer is the same, but
// uses a *Int
type ExamplePointer struct {
Age *int `json:"age,omitempty"`
Name string `json:"name"`
}

// PointerEncoding shows methods for
// dealing with nil/omitted values
func PointerEncoding() error {

// note that no age = nil age
e := ExamplePointer{}
if err := json.Unmarshal([]byte(jsonBlob), &e); err != nil
{
return err
}
fmt.Printf("Pointer Unmarshal, no age: %+v ", e)

value, err := json.Marshal(&e)
if err != nil {
return err
}
fmt.Println("Pointer Marshal, with no age:", string(value))

if err := json.Unmarshal([]byte(fulljsonBlob), &e);
err != nil {
return err
}
fmt.Printf("Pointer Unmarshal, with age = 0: %+v ", e)

value, err = json.Marshal(&e)
if err != nil {
return err
}
fmt.Println("Pointer Marshal, with age = 0:",
string(value))

return nil
}
  1. Create a file called nullencoding.go with the following content:
        package nulls

import (
"database/sql"
"encoding/json"
"fmt"
)

type nullInt64 sql.NullInt64

// ExampleNullInt is the same, but
// uses a sql.NullInt64
type ExampleNullInt struct {
Age *nullInt64 `json:"age,omitempty"`
Name string `json:"name"`
}

func (v *nullInt64) MarshalJSON() ([]byte, error) {
if v.Valid {
return json.Marshal(v.Int64)
}
return json.Marshal(nil)
}

func (v *nullInt64) UnmarshalJSON(b []byte) error {
v.Valid = false
if b != nil {
v.Valid = true
return json.Unmarshal(b, &v.Int64)
}
return nil
}

// NullEncoding shows an alternative method
// for dealing with nil/omitted values
func NullEncoding() error {
e := ExampleNullInt{}

// note that no means an invalid value
if err := json.Unmarshal([]byte(jsonBlob), &e); err != nil
{
return err
}
fmt.Printf("nullInt64 Unmarshal, no age: %+v ", e)

value, err := json.Marshal(&e)
if err != nil {
return err
}
fmt.Println("nullInt64 Marshal, with no age:",
string(value))

if err := json.Unmarshal([]byte(fulljsonBlob), &e);
err != nil {
return err
}
fmt.Printf("nullInt64 Unmarshal, with age = 0: %+v ", e)

value, err = json.Marshal(&e)
if err != nil {
return err
}
fmt.Println("nullInt64 Marshal, with age = 0:",
string(value))

return nil
}
  1. Create a new directory named example and navigate to it.
  2. Create a file called main.go with the following content:
        package main

import (
"fmt"

"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter3/nulls"
)

func main() {
if err := nulls.BaseEncoding(); err != nil {
panic(err)
}
fmt.Println()

if err := nulls.PointerEncoding(); err != nil {
panic(err)
}
fmt.Println()

if err := nulls.NullEncoding(); err != nil {
panic(err)
}
}
  1. Run go run main.go. You could also run the following:
$ go build
$ ./example

You should see the following output:

$ go run main.go
Regular Unmarshal, no age: {Age:0 Name:Aaron}
Regular Marshal, with no age: {"name":"Aaron"}
Regular Unmarshal, with age = 0: {Age:0 Name:Aaron}
Regular Marshal, with age = 0: {"name":"Aaron"}

Pointer Unmarshal, no age: {Age:<nil> Name:Aaron}
Pointer Marshal, with no age: {"name":"Aaron"}
Pointer Unmarshal, with age = 0: {Age:0xc42000a610 Name:Aaron}
Pointer Marshal, with age = 0: {"age":0,"name":"Aaron"}

nullInt64 Unmarshal, no age: {Age:<nil> Name:Aaron}
nullInt64 Marshal, with no age: {"name":"Aaron"}
nullInt64 Unmarshal, with age = 0: {Age:0xc42000a750
Name:Aaron}

nullInt64 Marshal, with age = 0: {"age":0,"name":"Aaron"}
  1. If you copied or wrote your own tests, go up one directory and run go test. Ensure that all tests pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.4.181