Friday, April 9, 2021

Golang - Introduction and the first program

What is $GOPATH



It is an environment variable that displays your computer's physical Go directory.

As a result, Go tools will search for Go source code files based on $GOPATH.
Furthermore, you can work on your Go code in this workspace.

The Go command 'go env' displays environment variables and setups.


    $ go env GOPATH
    /home/fcheng/go


So the go folder is in the current user's directory.


  $ echo ~
    /home/fcheng


The $GOPATH has three directories.
    /src
    /pkg
    /bin

All Go source code files should be placed under /src.

   
$ ls
    /src
        /github.com
            /chengys1986
                /go-project
                    main.go
        /fcheng
            /hello-world
                main.go


This folder structure is very helpful for organizing your projects and avoiding conflicts with other packages.


The First Go Code



We are going to use the example below to demonstrate its structure.

exp/main.go

package main

import "fmt"

func main() {
     fmt.Println("Hello World")
}


More details:

* The first code should be the "package" clause.
* 'package xxx' signifies that the current file, main.go, is a part of the xxx package.
* A unique package called "package main" enables Go to produce an executable file.
* Other packages are made available by "import xxx"
* "func" refers to an executable, reusable chunk of code.
* A unique function called "func main" tells Go where to begin.
* Another package that comes with the standard library is called "fmt" (formatting), which prints formatted strings to the console.


How to compile and run Go source code



We can start by typing "go" into your cmd, which will display a number of useful commands.


$ go
    Go is a tool for managing Go source code.

    Usage:

            go <command> [arguments]

    The commands are:

            bug         start a bug report
            build       compile packages and dependencies
    ...
   

First, navigate to your project directory.
To compile your Go project, run the command 'go build'.
You will then discover that a new file has been generated.


    $ cd ~/go/src/fcehng/hello-world/
$ go build
 $ tree ~/go/src/fcheng/hello-world/
    hello-world/
    ├── hello-world 
    └── main.go


The file is executable, therefore you can run it.
 

  $ ./hello-world


How to verify whether a file is executable or not.
 

$ file hello-world
    hello-world: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),


In brief: What does "go build" entail for us?


The code we write in 'main.go' cannot be recognize by machine (Those syntax is for human).

Therefore, we need 'go build' to translate those code to compiled code which machine can understand.


Does source code execution need building?



Use 'go run main.go' if you just want to quickly see the outcome of a simple modification.

We won't get an executable file from this command.


    $ cd ~/go/src/fcheng/hello-world/
    $ go run main.go



Package



Every file contained within a package ought to be located in the same physical directory.

There are two types of packages::

Executable

* Designed for use in running
* Executable (by go build and go run)
* Non-importable
* The package name must be'main'.
* It must incoude 'main' func

Library

* It is designed to be reusable.
* Non-executable
* Importable
* It can be given any package name, such as 'fmt'.
* No 'main' func


Scope and Declaration



Visibility is defined by scope.

Declaration means that declaring a unique name bound to a scope.

Scope is defined by where the name is declared: block, package, and file scopes.

1. Block Scope


Scope is surrounded by {} (braces)
It is visible after its declaration until '}'.

exp/main.go

package main

import "fmt"

func testFunc() {
     var test2 = "test2"
     fmt.Println(test2)
}

func main() {
     var test1 = "test1"

     // It attempts to access the variable in the same block scope.
     // Therefore, it works.
     fmt.Println(test1)

     // It tries to access the variable 'test2', which is only visible in the 'testFunc' block scope.
    // Therefore, it is not working.
     fmt.Println(test2)
}


2. Package Scope


Visibility via the package.

exp/hi.go

package main

import "fmt"

func hi() {
     fmt.Println("HI")
}


exp/main.go

package main

import "fmt"

func main() {
     fmt.Println("Hello!")

// Because 'hi.go' is in the same package, we don't need to import it.
// Furthermore, because 'hi.go' and 'main.go' are in the same package, the 'hi()' function is visible.
     hi()
}


Result:

   $ go run *.go
    Hello!
    HI


3. File Scope


Because the two files are on the same package, you may be confused by the example in package scope.

And why do I need to add 'fmt' to each file? Does it appear to be duplicate code?

Because 'import' is file scoped, only the file that is importing can utilize the imported libraries.


Statement



Statement instructs Go to do something.

One statement at a time. (Unless semicolons are used)

The execution flow is top to bottom, but statements (control flow statements like if) can vary the execution.


func main() {
     if 2 > 1 {
         fmt.Println("here")
     }
}



Expressions



It calculates one or more values.
Expressions should be used in conjunction with or within a statement.
It will return a value and cannot function without a statement.


    fmt.Println("Hello " + "World")
    fmt.Println(hi())
    fmt.Println(1 + 1)



Comments



* Single line comments
// this is comment


* Multiple line comments
/*
    this is comment
*/


Go Doc



During development, use 'go doc' to quickly inspect the function in the package you want to use.
Furthermore, several recent editors have already implemented it.

       
    $ go doc -src fmt Println
    package fmt // import "fmt"

    // Println formats using the default formats for its operands and writes to standard output.
    // Spaces are always added between operands and a newline is appended.
    // It returns the number of bytes written and any write error encountered.
    func Println(a ...interface{}) (n int, err error) {
     return Fprintln(os.Stdout, a...)
    }



Build your Library Package.


 
How to make a function exportable?

In this exercise, we will build a new library package that has a public function called 'PrintPCDetail()'.

/exp/printer/printer.go
package printer

import (
     "fmt"
     "runtime"
    "strconv"
)

/*
    Print PC information
    NOTE: The letter P is capitalized.
*/
func PrintPCDetail() {
     fmt.Println("CPU: " + strconv.Itoa(runtime.NumCPU()))
}


exp/main.go
package main

// Import our custom library package
import "fcheng/printer"

func main() {
// Call the public function of imported custom library package
     printer.PrintPCDetail()
}

 
Run the commands below to create modules and run the program.

$ go mod init exp
go: creating new go.mod: module exp go: to add module requirements and sums: go mod tidy

$ go run .
CPU: 12

 

No comments:

Post a Comment