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:
- Use json.Marshall because Marshal returns the JSON encoding
result, err := json.Marshal(FResult{ Status: "success", Message: fmt.Sprintf("%s", inputStr), })
- Check the error during convert
- 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.
- Check the error during convert
- 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:
- Navigate to our project directory
cd /d/Go/src/firstgo
- 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 }