Technical Thursday – Include external file with GoLang

In this week I would like to show a sensitive and important thing in GoLang which answers some questions and solve your problems if you just started development in Go(Lang).

 

When I started this – parellel with python – I was confused and I had some concerns about this language. (I still have some concerns…)

At first Iwould like to inform you this topic is not a brand new story and I am sure you can find many articles on internet on this area. Additionally there are severeal excellent documentation for Go.

 

Scenario

We have a main file which will use our modules. Our modules contain many useful and reusable functions and codes for different goals. We wouldn’t like to put every and each functions to a file because that is not so professional and not so efficient for the future.

We use it in this example: Your first library

 

Preparation

  • We use Atom for Go development.
  • We have to create a project and we have to create our project structure. This will be a simple structure.
    • main.go: main program
    • core.go: Package core contains useful functions

Solution

core.go

Our core module contains a function which provide a JSON as result. For this we have to do some things.

1. Package section

Package name

// Package core contains useful functions
package core

 

2. Import section

This contains the basic packages we would like to use during our implementation.

import (
	"encoding/json"
	"fmt"
)

We use here the JSON encoding and the “fmt”.

 

3. Result section – struct

We have to define a struct for result structure for JSON.

// FResult is a type of function results
type FResult struct {
	Status  string `json:"status"`
	Message string `json:"message"`
}

 

4. Functions section

Now this will solve our business requirements which is a simple JSON result function according to string input.

// GetJSONResult for json management
func GetJSONResult(inputStr string) FResult {
	result, err := json.Marshal(FResult{
		Status:  "success",
		Message: fmt.Sprintf("%s", inputStr),
	})
	if err != nil {
		panic(err)
	}

	var f FResult
	err = json.Unmarshal(result, &f)
	if err != nil {
		panic(err)
	}
	return f
}

This waits a string and gives back a “FResult” type result. Of course this is not so easy. Before that you have to fill your FResult struct related data with the related data, check errors then convert the whole object from/to JSON. (I know this is not a real scenario) And the trick here is the following:

  1. Use json.Marshall because Marshal returns the JSON encoding
    result, err := json.Marshal(FResult{ Status: "success", Message: fmt.Sprintf("%s", inputStr), })
  2. Check the error during convert
  3. Then use json.Unmarshall because Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by FResult If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
  4. Check the error during convert
  5. Finally it returns with the required result: return f

 

Now we can use it from main.go

main.go

This is our main file with the main function which will call our core related function.

1. Package section

Package name

package main

 

2. Import section

This contains the basic packages we would like to use during our implementation.

import (
 "firstgo/lib"
 "fmt"
)

IMPORTANT: For use an external library or function and include them you have to put here the related path from “src” directory. So if your project is in the “firstgo” directory and your module files inside the “lib” directory you have to import the “firstgo/lib” although your main file is also inside the “firstgo” directory.

3. Functions section

You have to define a main function which executed when you run your program. Here we have to put the module call part.

func main() {
	myResult := core.GetJSONResult("Example string")
	if myResult.Status == "success" {
		fmt.Printf("%s - %s", myResult.Status, myResult.Message)
	} else {
		fmt.Printf("%s", myResult.Status)
	}

}

Because we imported “firstgo/lib” directory and our “core.go” module is inside it we can use our module as we use in other language. I mean: <module>.<function>(<parameter list>)

As you can see I put the function result (which is a JSON object) to a variable then we can check it immediatelly without any further converting.

myResult := core.GetJSONResult("Example string")

 

4. Execution

Finally we just do the followings:

  1. Navigate to our project directory
    cd /d/Go/src/firstgo
    
  2. Run main.go file
     go run main.go

And here is the required result:

$ go run main.go
success - Example string

 

It is beautiful, isn’t it? 🙂


Both files are here:

main.go

package main

import (
	"firstgo/lib"
	"fmt"
)

func main() {
	myResult := core.GetJSONResult("Example string")
	if myResult.Status == "success" {
		fmt.Printf("%s - %s", myResult.Status, myResult.Message)
	} else {
		fmt.Printf("%s", myResult.Status)
	}

}

 

core.go

// Package core contains useful functions
package core

import (
	"encoding/json"
	"fmt"
)

// FResult is a type of function results
type FResult struct {
	Status  string `json:"status"`
	Message string `json:"message"`
}

// GetJSONResult for json management
func GetJSONResult(inputStr string) FResult {
	result, err := json.Marshal(FResult{
		Status:  "success",
		Message: fmt.Sprintf("%s", inputStr),
	})
	if err != nil {
		panic(err)
	}

	var f FResult
	err = json.Unmarshal(result, &f)
	if err != nil {
		panic(err)
	}
	return f
}