{"id":13713413,"url":"https://github.com/jeffotoni/goworkshopdevops","last_synced_at":"2025-10-29T04:18:28.037Z","repository":{"id":57624560,"uuid":"167730209","full_name":"jeffotoni/goworkshopdevops","owner":"jeffotoni","description":"Workshop material for 8 hours using golang","archived":false,"fork":false,"pushed_at":"2021-10-29T13:44:27.000Z","size":10825,"stargazers_count":69,"open_issues_count":0,"forks_count":10,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-20T06:44:20.869Z","etag":null,"topics":["go","golang","golang-language","gopath","mod-vendor","numeric-types","pointer-types","slice","slice-types"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffotoni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-26T19:32:18.000Z","updated_at":"2025-01-31T04:54:29.000Z","dependencies_parsed_at":"2022-08-26T22:12:29.135Z","dependency_job_id":null,"html_url":"https://github.com/jeffotoni/goworkshopdevops","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffotoni","download_url":"https://codeload.github.com/jeffotoni/goworkshopdevops/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245760541,"owners_count":20667886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","golang-language","gopath","mod-vendor","numeric-types","pointer-types","slice","slice-types"],"created_at":"2024-08-02T23:01:35.571Z","updated_at":"2025-10-29T04:18:27.948Z","avatar_url":"https://github.com/jeffotoni.png","language":null,"funding_links":[],"categories":["Others","Repositories"],"sub_categories":[],"readme":"\u003ch2 align=\"center\"\u003e\n  \u003cbr/\u003e\n  \u003cimg src=\"https://github.com/jeffotoni/gocompilation/blob/master/golang-compilation.png\" alt=\"logo\" width=\"670\" /\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n\u003c/h2\u003e\n\n# DevOps BootCamp\n\nMaterial for **8 hours** Practical Immersion **with Golang**\nThis is a material in Golang to be presented **\"face-to-face\"** in a **\"hand in hand\"** Workshop that will be done in 8 hours.\n\n# Golang Workshop DevOps\n---\n\nAll content aims at the basic level of the student many practical examples were made with details richness to make life easier than it is initiating.\n\nIf you know little and almost nothing programming will not be problem every manual was made to level starting to advanced.\nAll the difficulties I had when I started trying to contemplate this material.\nWe will try to improve the material all the time so we can have a reference when it comes to **Go**.\n\nI hope you all enjoy it and can serve as a base for learning and help several possible Gophers.\n\nThe content and references used are from the [Golang Official Site](https://golang.org) and the material being developed \nwhich is a compilation of all Golang language and can be checked here [jeffotoni/Compilation]( https://github.com/jeffotoni/goworkshopdevops#installation).\n\nSome presentations I made can be viewed here [Presentations](https://speakerdeck.com/jeffotoni).\n\nThere are thousands of references today regarding Golang, let's start at the beginning and we could not stop talking about [Golang Tour](https://tour.golang.org).\nWell that site here [Play Golang](https://play.golang.org/p/ayud1GTDJ0G) or [Play Go Space](https://goplay.space/#ayud1GTDJ0G) we can play Golang online.\n\nWe have a very interesting link that we have been able to search for packages written in Golang  check out this link: [Go Doc](https://godoc.org/)\n\nWe have this link that presents us as a manual all libs developed in Golang [Dev Docs](https://devdocs.io/go/)\n\nHere we find an awesome go, there are several lists as it is, and sometimes it's cool to check out some libs to help us with some projects. [awesome-go](https://awesome-go.com)\n\nSoon below some channels that I participate and can find me online.\n\n### Telegram:\n   - [gobr](https://t.me/go_br)\n### Slack: \n   - [gophers.slack.com](https://gophers.slack.com)\n      - Brazil\n      - Brasil\n      - General\n      - Go-kit\n      - Gotimefm\n      \n## Lab 01 Install and Commands Golang\n\n- [Overview](#overview)\n- [Introduction Installation](#introduction-installation)\n  - [Installation](#installation)\n    - [Linux](#linux)\n    - [$GOPATH](#gopath)\n    - [Test your installation](#test-your-installation)\n    - [Workspace](#workspace)\n    - [Outside GOPATH](#outside-gopath)\n- [Installation Docker](#installation-docker)\n\t- [Install Docker to Golang](#install-docker-to-golang)\n\t- [Compile your app Inside the Docker Container](#compile-your-app-inside-the-docker-container)\n\t- [Cross-compile Your app Inside the Docker Container](#cross-compile-your-app-inside-the-docker-container)\n- [Introduction Golang](#introduction-golang)\n  - [Golang Language](#golang-language)\n    - [Keywords](#keywords)\n    - [Operators and Punctuation](#operators-and-punctuation)\n    - [Println Print](#println-print)\n    - [Bufio NewWriter](#bufio-newWriter)\n    - [Func Main](#func-main)\n- [Go Commands](#go-commands)\n   - [Go Commands Introduction](#go-commands-introduction)\n   - [Go Run](#go-run) \n   - [Go Build](#go-build)\n   - [Go Install](#go-install)\n   - [Go Get](#go-get)\n   - [Go Mod](#go-mod)\n   - [Go Mod Init](#go-mod-init)\n   - [Go Mod Vendor](#go-mod-vendor)\n   - [GO111MODULE](#go111module)\n   - [Go Test](#go-test)\n\n## Lab 02 The Golang Types\n\n- [Types](#types)\n   - [Numeric Types](#numeric-types)\n   - [String Types](#string-types)\n   - [Pointer Types](#pointer-types)\n   - [Array Types](#array-types)\n   - [Slice Types](#slice-types)\n   - [Struct Types](#struct-types)\n   - [Struct In C](#struct-in-c)\n   - [Struct Type Tags Json](#struct-type-tags-json)\n   - [Fatih Structs to Map](#fatih-structs-to-map)\n   - [Map Types](#map-types)\n   - [Map Literals Continued](#map-literals-continued)\n   - [Channel Types](#channel-types)\n   - [Blank Identifier](#blank-identifier)\n   - [Interface Types](#interface-types)\n\t - [Here's an Interface as a Method](#heres-an-interface-as-a-method)\n\t - [Interface as Type](#interface-as-type)\n   - [Exercise One](#exercise-one)\n- [Control Structures](#control-structures)\n  - [Control](#control)\n    - [Control Return](#control-return)\n    - [Control Goto](#control-goto)\n    - [Control if Else](#control-if-else)\n    - [Control For Break Continue](#control-for-break-continue)\n    - [Control Switch Case Break](#control-switch-case-break)\n    - [Control Label](#control-label)\n    - [Control Range](#control-range)\n- [Errors](#Errors)\n  - [Introduction Errors](#introduction-Errors)\n    - [How Error Control Works](#how-error-control-works)\n    - [Errors New](#errorsnew)\n    - [Custom Errors](#custom-errors)    \n    - [fmt Errorf](#fmt-errorf)\n- [Functions](#functions)\n  - [Introduction Function](#introduction-function)\n    - [Return Multiple Values](#return-multiple-values) \n    - [Variadic Functions](#variadic-functions) \n    - [Functions as a Parameter](#functions-as-a-parameter) \n    - [Closures](#closures)\n    - [Recursion](#recursion)\n    - [Asynchronous Functions](#asynchronous-functions)\n- [Defer](#defer)\n- [Exercise Two](#exercise-two)\n\n## Lab 03 Parse with Golang, Yaml, Toml and Json\n\n- [Json](#Json)\n  - [Introduction](#introduction)\n    - [Json Marshal Encode](#json-marshal-encode)\n    - [Json MarshalIndent](#json-marshalIndent)\n    - [Option Omitempty](#option-omitempty)\n    - [Initialized Collections of Data](#initialized-collections-of-data)\n    - [Json NewEncoder](#json-newencoder)\n    - [Json Unmarshal Decode](#json-unmarshal-decode)\n    - [Generic JSON with Interface {} and Assertion](#generic-json-with-interface-and-assertion)\n    - [Dynamic Type](#dynamic-type)\n    - [What is Reflection](#what-is-reflection)\n    - [Making Reflect with Struct](#making-reflect-with-struct)\n- [Parse Json](#Json)\n\t- [Reading and Parsing a JSON File](#reading-and-parsing-a-json-file)\n\t- [Parsing with Structs](#parsing-with-structs)\n\t- [Parsing with Map and Interface](#parsing-with-map-and-interface)\n\t- [Parsing in Yaml Format Using Go](#parsing-in-yaml-format-using-go)\n\t- [Parsing in Toml Format Using Go](#parsing-in-toml-format-using-go)\n\t- [Parsing with Viper](#parsing-with-viper)\n- [Links Json to Golang](#links-json-to-golang)\n- [Exercise Three](#Exercise-three)\n\n## Lab 04 Building apis with net/http\n\n- [Introduction http](#introduction-http)\n\t- [Type Handler](#type-handler)\n\t- [Type HandlerFunc](#type-HandlerFunc)\n\t- [Func http Handlefunc](#func-http-handlefunc)\n\t- [Func http Handle](#func-http-handle)\n\t- [Func http Error](#func-http-error)\n\t- [Constants Common HTTP Methods](#constants-common-http-methods)\n\t- [Type ServeMux](#type-servemux)\n\t- [Type NewServeMux](#type-newservemux)\n\t- [Func ServeMux HandleFunc](#func-servemux-handleFunc)\n\t- [Type ServeMux Handle](#type-servemux-handle)\n\t- [Func ListenAndServe](#func-listenandserve)\n\t- [Func ListenAndServeTLS](#func-listenandservetls)\n\t- [Other Muxes](#other-muxes)\n\t- [Testing Http endpoints](#testing-Http-endpoints)\n\t- [Http Shutdown Gracefully](#http-shutdown-gracefully)\n\t- [Middleware](#middleware)\n\t- [http DetectContentType](#http-detectcontenttype)\n\t- [http DetectContentType](#http-detectcontenttype)    \n- [Exercise Five](#Exercise-five)\n- [net/http Client](#)\n  - [Introduction](#)\n    - [http.Transport](#)\n    - [http.Client](#)\n    - [http.Get](#)\n    - [http,Post](#)\n    - [http.NewRequest](#)\n    - [Context.WithCancel](#)\n- [Exercise Six](#Exercise-six)\n\n- [net/http Server Pages](#)\n  - [Introduction](#)\n    - [http.FileServer](#)\n    - [http.NotFound](#)\n    - [Disable http.FileServer](#)\n    - [http.Dir](#)\n    - [http.StripPrefix](#)    \n- [Exercise Seven](#Exercise-seven)\n\n## Lab 05 Using Golang to Create Command Line Programs\n\n- [Golang Cli](#golang-cli)\n  - [Introduction](#)\n  \t- [Environment Variables](#environment-variables)\n  \t- [Open and Read File](#open-write-file)\n  \t- [Write File](#write-file)\n  \t- [New Scanner and Scan](#new-scanner-and-scan)\n  \t- [Stdout](#stdout)\n    - [Stdin](#stdin)\n    - [Go Flag Types](#go-flag-types)\n    - [Go Flag Parse](go-flag-parse)\n    - [Go Flag PrintDefaults](go-flag-printDefaults)\n    - [Os Args](#os-args)\n    - [Func Init](#func-init)\n    - [Go Exec Command](#go-exec-command)\n    - [Parse Url](#parse-url)\n    - [Parse Yaml](#parse-yaml)\n\n- [Exercise Five](#Exercise-five)\n\n## Lab 06 Goroutine The Power\n\n- [Goroutine](#)\n  - [Introduction](#)\n    - [Channel](#)\n    - [Parallelism](#)\n    - [GOMAXPROCS](#)\n    - [WaitGroup](#)\n    - [Race Conditions](#)\n    - [Worker](#)\n    - [Context](#)\n    - [Ticker](#)\n    - [Singleton Connect Thread Safe](#)\n\n- [Exercise Four](#Exercise-four)\n\n### Overview\n---\n\nGo is a powerful language when it comes to competition and high performance, with a clean and efficient architecture. It grows year after \nyear and every day the communities grow even more.\n\nSome paradigms have been broken to make it a high performance language, where competition is one of its strengths. Go makes it easy to \ncreate programs that take full advantage of multicore and networked machines, while the new type system allows you to build flexible and modular programs.\n\nIt is a fast and statically compiled language that looks like a dynamically interpreted language. This feature Golang becomes \na unique language as the subject is web.\n\nGo is a compiled, competing, strong and statically typed programming language.\nIt is a \"General Use\" language that can be used to solve various problems and in different areas.\nProblems involving competition, web applications, high performance applications, development of APIs, communications sockets etc ... \nIs where language is increasingly becoming prominent in the market and in communities.\n\n### Introduction Installation\n\nIn golang the installation is all very simple and practical, for Linux, Mac and Windows.\n\nJust copy the files to the correct directory for each operating system and export the paths to the environment and prompt, golang is installed.\n\nLet's take a look at how we do this.\n\n### Installation \n---\n\nWe will download the file, unpack it and install it in /usr/local/go, if we have golang already installed in the machine we will have to remove the existing one to leave our installation as unique.\nLet's create our directory in our workspace and test to see if everything went well\n\n### Linux\n\n```bash\n$ sudo rm -rf /usr/local/go\n$ wget https://dl.google.com/go/go1.11.5.linux-amd64.tar.gz\n$ sudo tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz\n```\n\n### $GOPATH\n\n$GOPATH is the golang in your $HOME, this is necessary for your projects to use pkg and build properly. This was mandatory for all versions before version 1.11. The cool thing is that from now on we will not have to create projects in $GOPATH, we can create in any other directory that is not in $GOPATH.\n\nHere is the link to the versioning proposal [Proposal: Versioned Go Modules](https://go.googlesource.com/proposal/+/master/design/24301-versioned-go.md/) or [Go 1.11 Modules](https://github.com/golang/go/wiki/Modules/)\n\nWe'll detail how to work with **go mod**, it was one of the best experiences I had for versioning projects using Golang.\n\nLet's set up our environment to run Go. Add **/usr/local/go/bin** to the PATH environment variable. You can do this by adding this line to your **/etc/profile** (for a system-wide installation) or **$HOME/.profile**. \n\n```bash\n$ export PATH=$PATH:/usr/local/go/bin\n```\n\n**Note**: changes made to a profile file may not apply until the next time you log into your computer. To apply the changes immediately, just run the shell commands directly or execute them from the profile using a command such as source $HOME/.profile. \n\n```bash\n$ echo \"export GOPATH=$HOME/go\" \u003e\u003e $HOME/.profile\n$ echo \"export PATH=$PATH:/usr/local/go/bin\" \u003e\u003e $HOME/.profile\n$ echo \"export PATH=$PATH:$GOPATH/bin\" \u003e\u003e $HOME/.profile\n```\n\n### Test our Installation\n\nLet's run go version to see if everything is correct.\n\n```bash\n$ go version\ngo version go1.11.5 linux/amd64\n```\n\nCheck that Go is installed correctly by setting up a workspace and building a simple program, as follows. \n\nCreate your **workspace** directory, $HOME/go. (If you'd like to use a different directory, you will need to set the $GOPATH environment variable.)\n\nNext, make the directory src/hello inside your workspace, and in that directory create a file named hello.go that looks like:\n\n### Workspace\n\nWorkspace is our place of work, where we will organize our directories with our projects. As shown above, until **Go version 1.11** we were forced to do everything under the Workspace. $GOPATH Down Projects.\n\n**Example Hello**\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/go\n$ mkdir $HOME/go/src\n$ mkdir $HOME/go/src/hello\n$ vim $HOME/go/src/hello/hello.go\n```\n\n```bash\n$GOPATH/\n  |-src\n    |-hello\n      |-hello.go\n```\n\n**Example Project**\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/go/src/project1\n$ mkdir $HOME/go/src/project1/my-pkg\n$ mkdir $HOME/go/src/project1/my-cmd\n$ mkdir $HOME/go/src/project1/my-vendor\n$ mkdir $HOME/go/src/project1/my-logs\n$ mkdir $HOME/go/src/project1/my-models\n$ mkdir $HOME/go/src/project1/my-repo\n$ mkdir $HOME/go/src/project1/my-handler\n```\n\n```bash\n$GOPATH/\n  |-src\n    |-github.com/user/project1/\n        |-cmd (of project1)\n          |-main.go\n        |-vendor\n        |-logs\n        |-models\n        |-repo\n        |-handler\n    |-github.com/user/project2/\n      ....\n      ....\n```\n\nThe $GOPATH environment variable tells the Go tool where your workspace is located. \n\n```go\n$ go get github.com/user/project1\n```\n\nThe **go get** command fetches source repositories from the internet and places them in your workspace.\nPackage paths matter to the Go tool. Using \"github.com/...\" means the tool knows how to fetch your repository. \n\nIn the scenario above everything would have to stay in our **$GOPATH** so that our projects worked correctly.\n\n### Outside $GOPATH\n\nNow we can do our projects without being in $GOPATH, we can, for example, do it in any directory.\n\n**Project Outside GOPATH**\n\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/2019/project1\n$ mkdir $HOME/2019/project1/my-pkg\n$ mkdir $HOME/2019/project1/my-cmd\n$ mkdir $HOME/2019/project1/my-logs\n$ mkdir $HOME/2019/project1/my-models\n$ mkdir $HOME/2019/project1/my-repo\n$ mkdir $HOME/2019/project1/my-handler\n```\n```bash\n$HOME/\n  |-2019\n    |-github.com/user/project1/\n      |-cmd\n        |-main.go\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n\nWe can put our project in any directory now.\n\n```bash\n$HOME/\n  |-any-directory\n    |-github.com/user/project1/\n      |-cmd\n        |-main.go\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n\nFor the above scenario, we will have to use **go mod** in our project so that all external packages can work correctly, in this way we will be able to manage them correctly and version.\nMore information can be found here: [Wiki Go Modules](https://github.com/golang/go/wiki/Modules)\n\nPractical example of how you will proceed:\n```go\n$ go mod init github.com/user/project1\n```\n\n**Note**: \nWhen we use go mod in $GOPATH we will have to enable using GO111MODULE=on, so that it can work within the $GOPATH structure.\nSo our program can compile successfully.\n\n```go\n$ GO111MODULE=on go run cmd/main.go\n$ GO111MODULE=on go build -o project1 cmd/main.go\n```\n\n### Installation Docker\n\nIf we do not want to install directly on our operating system golang we can install it in a docker container.\n\nWe can upload a docker container with the installed language and compile and run our programs from this container.\n\nLet's check how we can do it below.\n\nMore information and details you can visit this link: [hub.docker](https://hub.docker.com/_/golang)\n\n### Install Docker to Golang\n\n```bash\n$ docker pull golang\n```\n\n### Compile Your app Inside The Docker Container\n\nThere may be occasions where it is not appropriate to run your app inside a container. To compile, but not run your app inside the \nDocker instance, you can write something like:\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.11.5 go build -v\n```\n\nThis will add your current directory as a volume to the container, set the working directory to the volume, and run the command go build which will tell go to compile the project in the working directory and output the executable to myapp. Alternatively, if you have a Makefile, you can run the make command inside your container.\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.11.5 make\n```\n\n### Cross-compile Your app Inside The Docker Container\nIf you need to compile your application for a platform other than linux/amd64 (such as windows/386):\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp -e GOOS=windows \\\n-e GOARCH=386 golang:1.11.5 go build -v\n```\n\n### Example main.go\n\nLet's do our test program, let's call it main.go\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main(){\n\tfmt.Println(\"My first program being compiled by a docker container!\")\n}\n```\n\nNow let's run a program to see if it works correctly\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/main -w /usr/src/main golang:1.11.5 go run main.go\n```\n\nOutput:\n```bash\nMy first program being compiled by a docker container!\n```\n\nCheck the version:\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/main -w /usr/src/main golang:1.11.5 go versio\n```\n\nOutput:\n```bash\ngo version go1.11.5 linux/amd64\n```\n\n### Introduction Golang\n---\n\nGo is a general-purpose language designed with systems programming in mind. It is strongly typed and garbage-collected and has explicit support for concurrent programming. \nPrograms are constructed from packages, whose properties allow efficient management of dependencies.\n\nThe grammar is compact and regular, allowing for easy analysis by automatic tools such as integrated development environments.\n\n### Golang Language\n---\n\n### Keywords\n\nThe following keywords are reserved and may not be used as identifiers. \n\n```bash\nbreak        default      func         interface    select\ncase         defer        go           map          struct\nchan         else         goto         package      switch\nconst        fallthrough  if           range        type\ncontinue     for          import       return       var\n```\n\n### Operators and Punctuation\n\nThe following character sequences represent operators (including assignment operators) and punctuation: \n\n```bash\n+    \u0026     +=    \u0026=     \u0026\u0026    ==    !=    (    )\n-    |     -=    |=     ||    \u003c     \u003c=    [    ]\n*    ^     *=    ^=     \u003c-    \u003e     \u003e=    {    }\n/    \u003c\u003c    /=    \u003c\u003c=    ++    =     :=    ,    ;\n%    \u003e\u003e    %=    \u003e\u003e=    --    !     ...   .    :\n     \u0026^          \u0026^=\n```\n\n### Println Print\n\nLet's learn how to send data to screen which is actually **stdout** standard output we will see more ahead with details on **stdout** and **stdin**.\n\nLet's know **print, println and fmt.Println**\n\nCurrent implementations provide several built-in functions useful during bootstrapping. These functions are documented for completeness but are not guaranteed to stay in the language. They do not return a result. \n\nImplementation restriction: **print** and **println** need not accept arbitrary argument types, but printing of boolean, numeric, and string types must be supported. \n\n**println is an built-in function** (into the runtime) which may eventually be removed, while the **fmt package** is in the standard library, which will persist.\n\n\n```bash\nFunction   Behavior\n\nprint      prints all arguments; formatting of arguments is implementation-specific\nprintln    like print but prints spaces between arguments and a newline at the end\n```\n\nusing print:\n```go\n// test print\npackage main\n\nfunc main() {\n   print(\"debugging my system with print\")\n}\n```\n\nOutput:\n```bash\ndebugging my system with print\n```\n\nusing println:\n```go\n// test println\npackage main\n\nfunc main() {\n   println(\"debugging my system with println\")\n}\n```\n\nOutput:\n```bash\ndebugging my system with println\n```\n\nusing fmt.Println:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n   fmt.Println(\"debugging my system with fmt.Println\")\n}\n```\n\nOutput:\n```bash\ndebugging my system with fmt.Println\n```\n\nThe goal of starting and running the print, println or fmt.Println command is to help us with the tests we will be performing from now on at every step of our Go learning.\n\n\n### Bufio NewWriter\n\n```bash\nbufio.Writer\n```\n\nDoing many small writes can hurt performance. Each write is ultimately a syscall and if doing frequently can put burden on the CPU. Devices like disks work better dealing with block-aligned data. To avoid the overhead of many small write operations Golang is shipped with bufio.Writer. Data, instead of going straight to destination (implementing io.Writer interface) are first accumulated inside the buffer and send out when buffer is full:\n\nLet’s visualise how buffering works with nine writes (one character each) when buffer has space for 4 characters:\n\n```bash\nproducer         buffer           destination (io.Writer)\n \n   a    -----\u003e   a\n   b    -----\u003e   ab\n   c    -----\u003e   abc\n   d    -----\u003e   abcd\n   e    -----\u003e   e      ------\u003e   abcd\n   f    -----\u003e   ef               abcd\n   g    -----\u003e   efg              abcd\n   h    -----\u003e   efgh             abcd\n   i    -----\u003e   i      ------\u003e   abcdefgh\n```\n\nCheck out the example below\n```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"os\"\n)\n\n// creating the write object pointer\n// so that we can receive value in every\n// scope of our program\nvar writer *bufio.Writer\n\nfunc main() {\n\t// All screen output will be redirected\n\t// to bufio.NewWriter\n\twriter = bufio.NewWriter(os.Stdout)\n\ts := \"How many stars does Orion have?\\n\"\n\tvar b byte = 'H'\n\n\twriter.WriteString(s)\n\twriter.WriteByte(b)\n\twriter.WriteString(\"\\n\")\n\n\t// when all the functions finishes it closes\n\t// the buffer and sends to the.Stdout\n\tdefer writer.Flush()\n}\n```\n\nOutput:\n```bash\nHow many stars does Orion have?\nH\n```\n\n### Func Main\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Printf(\"hello, Gophers\\n\")\n}\n```\n\nThen **build** it with the **go tool**: \n\n```go\n$ cd $HOME/go/src/hello\n$ go build\n```\n\nOr we can compile like this:\n```go\n$ cd $HOME/go/src/hello\n$ go build -o hello hello.go\n```\n\nThe command above will build an executable named hello in the directory alongside your source code. Execute it to see the greeting: \n\n```go\n$ ./hello\nhello, Gophers\n```\n\nCheck also the command **run** it with the go: \n\n```go\n$ go run hello.go\nhello, Gophers\n```\n\nIf you see the **\"hello, Gophers\"** message then your Go installation **is working**.\n\nYou can run **go install** to install the binary into your workspace's **bin** directory or **go clean -i** to remove it.\n\nExample: go install\n```go\n$ pwd\n$ $HOME/go/src/hello\n$ cd $HOME/go/src/hello\n$ go install\n$ ls -lhs $HOME/go/bin\n-rwxrwxr-x 1 user user 2,9M nov  8 03:11 hello\n```\n\nExample: go clean -i\n\n```go\n$ go clean -i \n$ ls -lhs $HOME/go/bin\n```\n\n### Go Commands\n---\n\n### Go Commands Introduction\n\nIn golang we have an arsenal to help us when it comes to compiling, testing, documenting, managing Profiling etc.\n\n```bash\nbug         start a bug report\nbuild       compile packages and dependencies\nclean       remove object files and cached files\ndoc         show documentation for package or symbol\nenv         print Go environment information\nfix         update packages to use new APIs\nfmt         gofmt (reformat) package sources\ngenerate    generate Go files by processing source\nget         download and install packages and dependencies\ninstall     compile and install packages and dependencies\nlist        list packages or modules\nmod         module maintenance\nrun         compile and run Go program\ntest        test packages\ntool        run specified go tool\nversion     print Go version\nvet         report likely mistakes in packages\n```\n\nUse \"go help \" for more information about a command.\n\n\n### Go Run\n---\n\nUsage:\n```bash\ngo run [build flags] [-exec xprog] package [arguments...]\n```\n\nRun compiles and runs the named main Go package. Typically the package is specified as a list of .go source files, but it may also be an import path, file system path, or pattern matching a single known package, as in 'go run .' or 'go run my/cmd'.\n\nBy default, 'go run' runs the compiled binary directly: 'a.out arguments...'. If the -exec flag is given, 'go run' invokes the binary using xprog: \n\nIf the -exec flag is not given, GOOS or GOARCH is different from the system default, and a program named go_$GOOS_$GOARCH_exec can be found on the current search path, 'go run' invokes the binary using that program, for example 'go_nacl_386_exec a.out arguments...'. This allows execution of cross-compiled programs when a simulator or other execution method is available.\n\nThe exit status of Run is not the exit status of the compiled binary.\n\nFor more about build flags, see 'go help build'. For more about specifying packages, see 'go help packages'.\n\nSee below an example:\n\n```go\n// test println\npackage main\n\nfunc main() {\n   println(\"Debugging my system with println\")\n}\n```\nGo run:\n```bash\ngo run println.go\n```\n\nOutput:\n```bash\nDebugging my system with println\n```\n\n### Go Build\n---\n\nBuild compiles the packages named by the import paths, along with their dependencies, but it does not install the results. \n\nWhen compiling packages, build ignores files that end in '_test.go'.\n\nThe -o flag, only allowed when compiling a single package, forces build to write the resulting executable or object to the named output file, instead of the default behavior described in the last two paragraphs.\n\nThe -i flag installs the packages that are dependencies of the target.\n\n```go\n$ go build [-o output] [-i] [build flags] [packages]\n```\n\nSee an example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Println(\"Workshop Golang 2019.\")\n}\n```\n\nOutput:\n```bash\nWorkshop Golang 2019.\n```\n\nNormal compilation\n```go\ngo build -o hello hello.go\n```\n\nOutput:\n```bash\n$ ls -lh \n-rwxrwxr-x 1 root root **1,9M** jan 18 12:42 hello\n-rw-rw-r-- 1 root root   75 jan 17 12:04 hello.go\n```\n\nLeaving the file smaller after compiling\n```go\ngo build -ldflags=\"-s -w\" hello.go\n```\n\nOutput:\n```bash\n$ ls -lh \n-rwxrwxr-x 1 root root **1,3M** jan 18 12:42 hello\n-rw-rw-r-- 1 root root   75 jan 17 12:04 hello.go\n```\n\n### Go Install\n---\n\nInstall packages and dependencies\n\nUsage:\n```bash\n$ go install [-i] [build flags] [packages]\n```\n\nInstall compiles and installs the packages named by the import paths.\n\nThe **-i flag** installs the dependencies of the named packages as well.\n\nFor more about the build flags, see 'go help build'. For more about specifying packages, see 'go help packages'.\n\n### Go Get\n---\n\nThe **'go get'** command changes behavior depending on whether the go command is running in module-aware mode or legacy GOPATH mode. This help text, accessible as 'go help module-get' even in legacy GOPATH mode, describes 'go get' as it operates in module-aware mode.\n\nUsage:\n```bash\n$ go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]\n```\n\nGet downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.\n\nLook at the flags accepted below:\n```bash\nThe -d flag instructs get to stop after downloading the packages; that is, it instructs get not to install the packages.\n\nThe -f flag, valid only when -u is set, forces get -u not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.\n\nThe -fix flag instructs get to run the fix tool on the downloaded packages before resolving dependencies or building the code.\n\nThe -insecure flag permits fetching from repositories and resolving custom domains using insecure schemes such as HTTP. Use with caution.\n\nThe -t flag instructs get to also download the packages required to build the tests for the specified packages.\n\nThe -u flag instructs get to use the network to update the named packages and their dependencies. By default, get uses the network to check out missing packages but does not use it to look for updates to existing packages.\n\nThe -v flag enables verbose progress and debug output.\n```\n\nExamples:\n```bash\n$ go get -v github.com/guptarohit/asciigraph\n$ go get -u github.com/mxk/go-sqlite\n$ go get -v github.com/google/uuid\n$ go get -v github.com/sirupsen/logru\n```\n\n\n### Go Mod\n---\n\nA module is a collection of related Go packages. Modules are the unit of source code interchange and versioning. The go command has direct support for working with modules, including recording and resolving dependencies on other modules. Modules replace the old GOPATH-based approach to specifying which source files are used in a given build. \n\nUsage:\n\n```bash\n$ go mod \u003ccommand\u003e [arguments]\n```\nA module is defined by a tree of Go source files with a **go.mod** file in the tree's root directory. The directory containing the go.mod file is called the module root. Typically the module root will also correspond to a source code repository root (but in general it need not). The module is the set of all Go packages in the module root and its subdirectories, but excluding subtrees with their own go.mod files.\n\nThe \"module path\" is the import path prefix corresponding to the module root. The go.mod file defines the module path and lists the specific versions of other modules that should be used when resolving imports during a build, by giving their module paths and versions.\n\nFor example, this go.mod declares that the directory containing it is the root of the module with path example.com/m, and it also declares that the module depends on specific versions of golang.org/x/text and gopkg.in/yaml.v2: \n\n```bash\n$ go mod init github.com/user/gomyproject\n\nrequire (\n  golang.org/x/text v0.3.0\n  gopkg.in/yaml.v2 v2.1.0\n)\n```\nThe go.mod file can also specify replacements and excluded versions that only apply when building the module directly; they are ignored when the module is incorporated into a larger build. For more about the go.mod file, see 'go help go.mod'.\n\nTo start a new module, simply create a go.mod file in the root of the module's directory tree, containing only a module statement. The 'go mod init' command can be used to do this: \n\n```bash\n$ go mod init github.com/user/gomyproject\n```\nIn a project already using an existing dependency management tool like **godep, glide, or dep, 'go mod init'** will also add require statements matching the existing configuration.\n\nOnce the go.mod file exists, no additional steps are required: go commands like **'go build'**, **'go test'**, or even **'go list'** will automatically add new dependencies as needed to satisfy imports.\n\nThe commands are: \n\n```bash\ndownload    download modules to local cache\nedit        edit go.mod from tools or scripts\ngraph       print module requirement graph\ninit        initialize new module in current directory\ntidy        add missing and remove unused modules\nvendor      make vendored copy of dependencies\nverify      verify dependencies have expected content\nwhy         explain why packages or modules are needed\n```\nUse \"go help mod \u003ccommand\u003e\" for more information about a command.\n\n\n### Go Mod Init\n\nInitialize new module in current directory\n\nUsage:\n\n```bash\n$ go mod init [module]\n```\n\nInit initializes and writes a new **go.mod** to the current directory, in effect creating a new module rooted at the current directory. The file go.mod must not already exist. If possible, init will guess the module path from import comments (see 'go help importpath') or from version control configuration. To override this guess, supply the module path as an argument. \n\n\n```bash\n$ go mod init github.com/user/gomyproject2\n\nrequire (\n  github.com/dgrijalva/jwt-go v3.2.0+incompatible\n  github.com/didip/tollbooth v4.0.0+incompatible\n  github.com/go-sql-driver/mysql v1.4.1\n  github.com/patrickmn/go-cache v2.1.0+incompatible // indirect\n  golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc\n  golang.org/x/time v0.0.0-20181108054448-85acf8d2951c // indirect\n)\n```\n\n### Go Mod Vendor\n\nThe go mod vendor command will download all dependencies to the \"vendor\" directory.\nWhen using go mod init the packages are not in your directory.\n\n```bash\n$ cd gomyproject2\n$ go mod vendor\n```\n\nOutput:\n```bash\n$ ls -lh vendor\ntotal 8,0K\ndrwxrwxr-x 3 root root 4,0K jan 27 01:47 github.com\n-rw-rw-r-- 1 root root  137 jan 27 01:47 modules.txt\n```\n\n### GO111MODULE\n\nGo 1.11 includes preliminary support for Go modules, including a new module-aware 'go get' command. We intend to keep revising this support, while preserving compatibility, until it can be declared official (no longer preliminary), and then at a later point we may remove support for work in GOPATH and the old 'go get' command.\n\nThe quickest way to take advantage of the new Go 1.11 module support is to check out your repository into a directory outside GOPATH/src, create a go.mod file (described in the next section) there, and run go commands from within that file tree.\n\nFor more fine-grained control, the module support in Go 1.11 respects a temporary environment variable, GO111MODULE, which can be set to one of three string values: off, on, or auto (the default). If GO111MODULE=off, then the go command never uses the new module support. Instead it looks in vendor directories and GOPATH to find dependencies; we now refer to this as \"GOPATH mode.\" If GO111MODULE=on, then the go command requires the use of modules, never consulting GOPATH. We refer to this as the command being module-aware or running in \"module-aware mode\". If GO111MODULE=auto or is unset, then the go command enables or disables module support based on the current directory. Module support is enabled only when the current directory is outside GOPATH/src and itself contains a go.mod file or is below a directory containing a go.mod file.\n\nIn module-aware mode, GOPATH no longer defines the meaning of imports during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod) and installed commands (in GOPATH/bin, unless GOBIN is set).\n\n\nCheck below how we use the command:\n```bash\n$ GO111MODULE=on go run myprogram.go\n$ GO111MODULE=on go build myprogram.go\n```\nWhen our project is not in our **$GOPATH** it is not necessary to use **GO111MODULE**, but when our project is in **$GOPATH** and we want to use **\"go mod\"** we need to inform this to the compiler using **GO111MODULE**...\n\n\n### Go Test\n---\n\nTest packages\n\nUsage:\n\n```go\n$ go test [build/test flags] [packages] [build/test flags \u0026 test binary flags]\n```\n\nGo **test** automates testing the packages named by the import paths. It prints a summary of the test results in the format: \n\n```bash\n=== RUN   TestWhatever\n--- PASS: TestWhatever (0.00s)\nPASS\nok    command-line-arguments  0.001s\n```\n\nThe test package runs side-by-side with the go test command. The package test should have the suffix \"\\_test.go\".\nWe can split the tests into several files following this convention. For example: \"myprog1_test.go\" and \"myprog2_test.go\".\n\nWe should put our test functions in these test files.\n\nEach test function is an exported public function whose name begins with **\"Test\"**, accepts a pointer to a **testing.T** object, and returns nothing. Like this:\n\nExample one / myprog1_test:\n```go\npackage main\n\nimport \"testing\"\n\nfunc TestWhatever(t *testing.T) {\n    // Your test code goes here\n}\n```\n\n```bash\n$ go test -v\n```\n\nOutput:\n```bash\n=== RUN   TestWhatever\n--- PASS: TestWhatever (0.00s)\nPASS\nok    command-line-arguments  0.001s\n```\n\nThe T object provides several methods that we can use to indicate failures or log errors.\n\nExample two / myprog2_test:\n```go\npackage main\n\nimport \"testing\"\n\nfunc TestSum(t *testing.T) {\n  x := 1 + 1\n  if x != 11 { // forcing the error\n    t.Error(\"Error! 1 + 1 is not equal to 2, I got\", x)\n  }\n}\n```\n\n```bash\n$ go test -v\n```\n\nOutput:\n```bash\n=== RUN   TestSum\n-- FAIL: TestSum (0.00s)\n    myprog1_test.go:12: Error! 1 + 1 is not equal to 2, I got 2\nFAIL\nFAIL  command-line-arguments  0.001s\n```\n\nIn this example we will make an examination as it would be in our projects.\n\nIn this program I will pass parameter at compile time or in our execution to facilitate and also serve as an example the use of **\"ldflags\"** that we can use in both **go run -ldflags ** and **go build -ldflags**\n\nFrom a check in our code below / main.go:\n```go\nimport \"strconv\"\n\nimport (\n  \"github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/math\"\n)\n\nvar (\n  x, y   string\n  xi, yi int\n)\n\nfunc init() {\n  xi, _ = strconv.Atoi(x)\n  yi, _ = strconv.Atoi(y)\n}\n\nfunc main() {\n  println(math.Sum(xi, yi))\n}\n```\n\nNow we have a Sum function in a pkg that we create in **pkg/math/sum.go**\n\n```go\npackage math\n\nfunc Sum(x, y int) int {\n  return x + y\n}\n```\n\nWe created our test file in **pkg/math/sum_test.go**\n\n```go\npackage math\n\nimport \"testing\"\n\nfunc TestSum(t *testing.T) {\n  type args struct {\n    x int\n    y int\n  }\n  tests := []struct {\n    name string\n    args args\n    want int\n  }{\n    // TODO: Add test cases.\n    {\"test_1: \", args{2, 2}, 4},\n    {\"test_2: \", args{-2, 6}, 4},\n    {\"test_3: \", args{-4, 8}, 4},\n    {\"test_4: \", args{5, 7}, 12},\n    {\"test_5: \", args{8, 8}, 15}, // forcing the error\n  }\n  for _, tt := range tests {\n    t.Run(tt.name, func(t *testing.T) {\n      if got := Sum(tt.args.x, tt.args.y); got != tt.want {\n        t.Errorf(\"Sum() = %v, want %v\", got, tt.want)\n      }\n    })\n  }\n}\n```\n\n```bash\n$ cd pkg/math/\n$ go test -v\n```\n\nOutput:\n```bash\n=== RUN   TestSum\n=== RUN   TestSum/test_1:_\n=== RUN   TestSum/test_2:_\n=== RUN   TestSum/test_3:_\n=== RUN   TestSum/test_4:_\n=== RUN   TestSum/test_5:_\n--- FAIL: TestSum (0.00s)\n    --- PASS: TestSum/test_1:_ (0.00s)\n    --- PASS: TestSum/test_2:_ (0.00s)\n    --- PASS: TestSum/test_3:_ (0.00s)\n    --- PASS: TestSum/test_4:_ (0.00s)\n    --- FAIL: TestSum/test_5:_ (0.00s)\n        sum_test.go:29: Sum() = 16, want 15\nFAIL\nexit status 1\nFAIL  github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/pkg/math  0.001s\n```\n\nIt converts to json the output of the tests\n\n```bash\n$ go test -v -json\n```\n\ncheck your output on your terminal screen to view json output.\n\n---\n\nNow that we've saved our pkg / math / sum.go let's do a main.go by making the call in this packet.\nBut first let's run go mod to manage our packages and versions correctly.\n\nCheck the command below:\n```bash\n$ go mod init github.com/jeffotoni/goworkshopdevops/examples/tests/pkg\n```\n\nOutput:\n```bash\ngo: finding github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/math latest\ngo: finding github.com/jeffotoni/goworkshopdevops/examples/tests latest\ngo: finding github.com/jeffotoni/goworkshopdevops/examples latest\ngo: finding github.com/jeffotoni/goworkshopdevops latest\ngo: downloading github.com/jeffotoni/goworkshopdevops v0.0.0-20190127023912-a2fa53299867\n0\n```\n\nNow we can do **build** or **run** in our **main.go**.\nLet's run go run using the **\"-ldflags\"** flag to pass parameter to our code at compile time.\n\n```bash\n$ go run -ldflags \"-X main.x=2 -X main.y=3\" main.go\n```\n\nOutput:\n```bash\n5\n```\n\n```bash\n$ go run -ldflags \"-X main.x=7 -X main.y=3\" main.go\n```\n\nOutput:\n```bash\n10\n```\n\n## Lab 02 Types with Golang\n---\n\n### Types\n---\n\nA type determines a set of values together with operations and methods specific to those values. A type may be denoted by a type name, if it has one, or specified using a type literal, which composes a type from existing types. \n\nThe language predeclares certain type names. Others are introduced with type declarations. Composite types—array, struct, pointer, function, interface, slice, map, and channel types—may be constructed using type literals.\n\nEach type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its type declaration. \n\nExample:\n```bash\ntype (\n    A1 = string\n    A2 = A1\n)\n\ntype (\n    B1 string\n    B2 B1\n    B3 []B1\n    B4 B3\n)\n```\n\nThe underlying type of string, A1, A2, B1, and B2 is string. The underlying type of []B1, B3, and B4 is []B1. \n\n\n### Numeric Types\n\nA numeric type represents sets of integer or floating-point values. The predeclared architecture-independent numeric types are: \n\n```bash\nuint8       the set of all unsigned  8-bit integers (0 to 255)\nuint16      the set of all unsigned 16-bit integers (0 to 65535)\nuint32      the set of all unsigned 32-bit integers (0 to 4294967295)\nuint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)\n\nint8        the set of all signed  8-bit integers (-128 to 127)\nint16       the set of all signed 16-bit integers (-32768 to 32767)\nint32       the set of all signed 32-bit integers (-2147483648 to 2147483647)\nint64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)\n\nfloat32     the set of all IEEE-754 32-bit floating-point numbers\nfloat64     the set of all IEEE-754 64-bit floating-point numbers\n\ncomplex64   the set of all complex numbers with float32 real and imaginary parts\ncomplex128  the set of all complex numbers with float64 real and imaginary parts\n\nbyte        alias for uint8\nrune        alias for int32\n```\nThe value of an n-bit integer is n bits wide and represented using two's complement arithmetic.\n\nThere is also a set of predeclared numeric types with implementation-specific sizes:\n\n```bash\nuint     either 32 or 64 bits\nint      same size as uint\nuintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value\n```\n\nTo avoid portability issues all numeric types are defined types and thus distinct except byte, which is an alias for uint8, and rune, which is an alias for int32. Conversions are required when different numeric types are mixed in an expression or assignment. For instance, int32 and int are not the same type even though they may have the same size on a particular architecture. \n\n### String Types\n\nA string type represents the set of string values. A string value is a (possibly empty) sequence of bytes. Strings are immutable: once created, it is impossible to change the contents of a string. The predeclared string type is string; it is a defined type.\n\nThe length of a string s (its size in bytes) can be discovered using the built-in function len. The length is a compile-time constant if the string is a constant. A string's bytes can be accessed by integer indices 0 through len(s)-1. It is illegal to take the address of such an element; if s[i] is the i'th byte of a string, \u0026s[i] is invalid. \n\n```go\npackage main\n\nimport \"fmt\"\n\ntype S string\n\nvar (\n  String = \"@jeffotoni\"\n)\n\nfunc main() {\n  var text string\n  var str S\n\n  mypicture := \"@Photograph-jeffotoni\"\n  str = \"@workshop-devOpsBh\"\n  text = \"@jeffotoni-golang\"\n\n  fmt.Println(str)\n  fmt.Println(String)\n  fmt.Println(text)\n  fmt.Println(mypicture)\n\n  // example string\n  s := \"日本語\"\n  fmt.Printf(\"Glyph:             %q\\n\", s)\n  fmt.Printf(\"UTF-8:             [% x]\\n\", []byte(s))\n  fmt.Printf(\"Unicode codepoint: %U\\n\", []rune(s))\n}\n```\nOutput:\n\n```go\n@workshop-devOpsBh\n@jeffotoni\n@jeffotoni-golang\n@Photograph-jeffotoni\nGlyph:             \"日本語\"\nUTF-8:             [e6 97 a5 e6 9c ac e8 aa 9e]\nUnicode codepoint: [U+65E5 U+672C U+8A9E]\n```\n### Pointer Types\n\nStruct fields can be accessed through a struct pointer.\n\nTo access the field X of a struct when we have the struct pointer p we could write (*p).X. However, that notation is cumbersome, so the language permits us instead to write just p.X, without the explicit dereference.\n\nA pointer type denotes the set of all pointers to variables of a given type, called the base type of the pointer. The value of an uninitialized pointer is nil.\n\n```bash\nPointerType = \"*\" BaseType .\nBaseType    = Type .\n```\n\n```bash\n*Point\n*[4]int\n```\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\ntype Vertex struct {\n  X int\n  Y int\n}\n\nfunc main() {\n  v := Vertex{1, 2}\n  p := \u0026v\n  p.X = 1e9\n  fmt.Println(v)\n  fmt.Println(p.Y)\n}\n```\nOutput:\n```bash\n{1000000000 2}\n2\n```\nFor every type that is declared, either by you or the language itself, you get for free a complement pointer type you can use for sharing. There already exists a built-in type named int so there is a complement pointer type called *int.\n\nAll pointer types have the same two characteristics. First, they start with the character *. Second, they all have the same memory size and representation, which is a 4 or 8 bytes that represent an address. On 32bit architectures (like the playground), pointers require 4 bytes of memory and on 64bit architectures (like your machine), they require 8 bytes of memory.\n\nExample:\n```go\npackage main\n\nfunc main() {\n\n  var a int\n  inc := \u0026a\n  *inc = 2\n  *inc++\n  println(\"inc:\\tValue Of[\", inc, \"]\\tAddr Of[\", \u0026inc, \"]\\tValue Points To[\", *inc, \"]\")\n}\n```\n\nOutput:\n```bash\ninc:  Value Of[ 0xc000036778 ]  Addr Of[ 0xc000036780 ]  Value Points To[ 3 ]\n```\n\nFor an operand x of type T, the address operation \u0026x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal. If the evaluation of x would cause a run-time panic, then the evaluation of \u0026x does too.\n\nFor an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. If x is nil, an attempt to evaluate *x will cause a run-time panic.\n\n```bash\n\u0026x\n\u0026a[f(2)]\n\u0026Point{2, 3}\n*p\n*pf(x)\n\nvar x *int = nil\n*x   // causes a run-time panic\n\u0026*x  // causes a run-time panic\n```\n\nSee the example below:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  var a int = 100  /* actual variable declaration */\n  var pa *int      /* pointer variable declaration */\n  var pointer *int /* pointer variable declaration */\n\n  pa = \u0026a /* store address of a in pointer variable*/\n\n  fmt.Printf(\"Address of a variable: %x\\n\", \u0026a)\n\n  /* address stored in pointer variable */\n  fmt.Printf(\"Address stored in ip variable: %x\\n\", pa)\n\n  /* access the value using the pointer */\n  fmt.Printf(\"Value of *ip variable: %d\\n\", *pa)\n\n  /* succeeds if p is not nil */\n  if pa != nil {\n    fmt.Println(\"success is not nil\")\n  }\n\n  /* succeeds if p is null */\n  if (pointer) == nil {\n    fmt.Println(\"success pointer is nil\")\n  }\n}\n```\n\nOutput:\n```bash\nAddress of a variable: c0000160c8\nAddress stored in ip variable: c0000160c8\nValue of *ip variable: 100\nsuccess is not nil\nsuccess pointer is nil\n```\n\n### Array Types\n\nAn array is a numbered sequence of elements of a single type, called the element type. The number of elements is called the length and is never negative.\n\n```bash\nArrayType   = \"[\" ArrayLength \"]\" ElementType .\nArrayLength = Expression .\nElementType = Type .\n```\n\nThe length is part of the array's type; it must evaluate to a non-negative constant representable by a value of type int. The length of array a can be discovered using the built-in function len. The elements can be addressed by integer indices 0 through len(a)-1. Array types are always one-dimensional but may be composed to form multi-dimensional types.\n\n```\n[32]byte\n[2*N] struct { x, y int32 }\n[1000]*float64\n[3][5]int\n[2][2][2]float64  // same as [2]([2]([2]float64))\n```\n\nAn array's length is part of its type, so arrays cannot be resized. This seems limiting, but don't worry; Go provides a convenient way of working with arrays. \n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n  // var a []string // wrong\n\n  // An array of 10 integers\n  var a1 [5]int\n  a1[0] = 5\n  a1[1] = 4\n  a1[2] = 3\n  a1[3] = 2\n  a1[4] = 1\n  fmt.Println(a1)\n}\n```\n\nOutput:\n```bash\n[5 4 3 2 1]\n```\n\n### Slice Types\n\nA slice is a descriptor for a contiguous segment of an underlying array and provides access to a numbered sequence of elements from that array. A slice type denotes the set of all slices of arrays of its element type. The value of an uninitialized slice is nil. \n\nAn array has a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array. In practice, slices are much more common than arrays.\n\nThe type **[]T** is a slice with elements of **type T**.\n\nA slice is formed by specifying two indices, a low and high bound, separated by a colon:\n\n```bash\na[low : high]\n```\n\nThis selects a half-open range which includes the first element, but excludes the last one.\n\nThe following expression creates a slice which includes elements 1 through 3 of a: \n\n```bash\na[1:4]\n```\n\nExample:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  primes := [7]int{2, 3, 5, 7, 11, 13, 14}\n  \n  var p []int = primes[2:5]\n  fmt.Println(p)\n}\n```\nOutput:\n```bash\n[5 7 11]\n```\n\nA new, initialized slice value for a given element type T is made using the built-in function make, which takes a slice type and parameters specifying the length and optionally the capacity. A slice created with make always allocates a new, hidden array to which the returned slice value refers. That is, executing.\n\n```bash\nmake([]T, length, capacity)\n```\n\nProduces the same slice as allocating an array and slicing it, so these two expressions are equivalent:\n\n```bash\nmake([]int, 50, 100)\nnew([100]int)[0:50]\n```\n\nLike arrays, slices are always one-dimensional but may be composed to construct higher-dimensional objects. With arrays of arrays, the inner arrays are, by construction, always the same length; however with slices of slices (or arrays of slices), the inner lengths may vary dynamically. Moreover, the inner slices must be initialized individually.\n\n Slices can be created with the built-in make function; this is how you create dynamically-sized arrays.\n\nThe make function allocates a zeroed array and returns a slice that refers to that array: \n\n```go\na := make([]int, 4)  // len(a)=4\n```\nExample:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  a := make([]int,4)\n  a[0]=12\n  fmt.Println(\"a\", a)\n\n  b := make([]int, 0, 5)\n  fmt.Println(\"b\", b)\n  \n  c := b[:2]\n  fmt.Println(\"c\", c)\n}\n```\nOutput:\n```bash\na [12 0 0 0]\nb []\nc [0 0]\n```\n\nA slice of type T is declared using []T. For example, Here is how you can declare a slice of type int -\n\n```go\n// Slice of type `int`\nvar slice []int\n\n// Slice of type `string`\nvar slice []string\n\n// Slice of type `string` with parameter variadic\nvar lang = [...]string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n```\n\nYou can create a slice using a slice literal like this -\n\n```go\n// Creating a slice using a slice literal\nvar s = []int{3, 5, 7, 9, 11, 13, 17}\n```\n\nThe expression on the right-hand side of the above statement is a slice literal. The slice literal is declared just like an array literal, except that you do not specify any size in the square brackets [].\n\nWhen you create a slice using a slice literal, it first creates an array and then returns a slice reference to it.\n\nLet’s see:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Creating a slice using a slice literal\n\tvar s = []string{\"@jeffotoni\", \"@awsbrasil\", \"@devopsbh\", \"@go_br\"}\n\n\t// Short hand declaration\n\tt := []int{2, 4, 8, 16, 32, 64}\n\n\tfmt.Println(\"s = \", s, len(s))\n\tfmt.Println(\"t = \", t, len(t))\n}\n```\nOutput:\n```bash\ns =  [@jeffotoni @awsbrasil @devopsbh @go_br] 4\nt =  [2 4 8 16 32 64] 6\n```\n\nSince a slice is a segment of an array, we can create a slice from an array.\n\nTo create a slice from an array a, we specify two indices low (lower bound) and high (upper bound) separated by a colon\n\n```bash\n// Obtaining a slice from an array `a`\na[low:high]\n```\n\nThe above expression selects a slice from the array a. The resulting slice includes all the elements starting from index low to high, but excluding the element at index high.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Creating a slice using a slice literal\n\tvar groups = [5]string{\"@awsbrasil\", \"@devopsbh\", \"@go_br\", \"@devopsbr\", \"@docker\"}\n\n\t// Creating a slice from the array\n\tvar s []string = groups[2:5]\n\n\ts2 := s[1:3]\n\ts3 := s[:3]\n\ts4 := s[2:]\n\ts5 := s[:]\n\n\tfmt.Println(\"Array groups = \", groups, \"len:\", len(groups), \"cap:\", cap(groups))\n\tfmt.Println(\"Slice s = \", s, \"len:\", len(s), \"cap:\", cap(s))\n\tfmt.Println(\"Slice s = \", s2, \"len:\", len(s2), \"cap:\", cap(s2))\n\tfmt.Println(\"Slice s = \", s3, \"len:\", len(s3), \"cap:\", cap(s3))\n\tfmt.Println(\"Slice s = \", s4, \"len:\", len(s4), \"cap:\", cap(s4))\n\tfmt.Println(\"Slice s = \", s5, \"len:\", len(s5), \"cap:\", cap(s5))\n}\n```\n\nOutput:\n```bash\nArray groups =  [@awsbrasil @devopsbh @go_br @devopsbr @docker] len: 5 cap: 5\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\nSlice s =  [@devopsbr @docker] len: 2 cap: 2\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\nSlice s =  [@docker] len: 1 cap: 1\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\n```\n\nThe copy() function copies elements from one slice to another. Its signature looks like this\n\n```go\nfunc copy(dst, src []T) int\n```\n\nIt takes two slices - a destination slice, and a source slice. It then copies elements from the source to the destination and returns the number of elements that are copied.\n\nNote that the elements are copied only if the destination slice has sufficient capacity.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tsrc := []string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n\tdest := make([]string, 2)\n\n\tnumElementsCopied := copy(dest, src)\n\n\tfmt.Println(\"src = \", src)\n\tfmt.Println(\"dest = \", dest)\n\tfmt.Println(\"Number of elements copied from src to dest = \", numElementsCopied)\n}\n```\n\nOutput:\n```bash\nsrc =  [Erlang Elixir Haskell Clojure Scala]\ndest =  [Erlang Elixir]\nNumber of elements copied from src to dest =  2\n```\nThe append() function appends new elements at the end of a given slice. Following is the signature of append function.\n\n```go\nfunc append(s []T, x ...T) []T\n```\n\nIt takes a slice and a variable number of arguments x …T. It then returns a new slice containing all the elements from the given slice as well as the new elements.\n\nIf the given slice doesn’t have sufficient capacity to accommodate new elements then a new underlying array is allocated with bigger capacity. All the elements from the underlying array of the existing slice are copied to this new array, and then the new elements are appended.\n\nHowever, if the slice has enough capacity to accommodate new elements, then the append() function re-uses its underlying array and appends new elements to the same array.\n\nLet’s see an example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tslice1 := []string{\"Clojure\", \"Scala\", \"Elixir\"}\n\tslice2 := append(slice1, \"Assembly\", \"Rust\", \"Go\")\n\tfmt.Printf(\"slice1 = %v, len = %d, cap = %d\\n\", slice1, len(slice1), cap(slice1))\n\tfmt.Printf(\"slice2 = %v, len = %d, cap = %d\\n\", slice2, len(slice2), cap(slice2))\n\tslice1[0] = \"C++\"\n\tfmt.Println(\"\\nslice1 = \", slice1)\n\tfmt.Println(\"slice2 = \", slice2)\n\t\n\t// slice nil\n\tvar s []string\n\n\t// Appending to a nil slice\n\ts = append(s, \"Java\", \"C\", \"Lisp\", \"Haskell\")\n\tfmt.Printf(\"\\ns = %v, len = %d, cap = %d\\n\", s, len(s), cap(s))\n}\n```\n\nOutput:\n```bash\nslice1 = [Clojure Scala Elixir], len = 3, cap = 3\nslice2 = [Clojure Scala Elixir Assembly Rust Go], len = 6, cap = 6\n\nslice1 =  [C++ Scala Elixir]\nslice2 =  [Clojure Scala Elixir Assembly Rust Go]\n\ns = [Java C Lisp Haskell], len = 4, cap = 4\n```\n\n### Struct Types\n\nA struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique.\n\n```go\nStructType    = \"struct\" \"{\" { FieldDecl \";\" } \"}\" .\nFieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .\nEmbeddedField = [ \"*\" ] TypeName .\nTag           = string_lit .\n\n// An empty struct.\nstruct{}\n\n// A struct with 6 fields.\nstruct {\n  x, y int\n  u float32\n  _ float32  // padding\n  A *[]int\n  F func()\n}\n```\n\nA field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.\n\n```go\n// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4\nstruct {\n  T1        // field name is T1\n  *T2       // field name is T2\n  P.T3      // field name is T3\n  *P.T4     // field name is T4\n  x, y int  // field names are x and y\n}\n```\n\nThe following declaration is illegal because field names must be unique in a struct type:\n\n```go\nstruct {\n  T     // conflicts with embedded field *T and *P.T\n  *T    // conflicts with embedded field T and *P.T\n  *P.T  // conflicts with embedded field T and *T\n}\n```\nA struct is a collection of fields. \n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Vertex struct {\n  X int\n  Y int\n}\n\nfunc main() {\n  v := Vertex{10, 201}\n  v.X = 4\n  fmt.Println(v)\n}\n```\n\nOutput:\n```bash\n{4 201}\n```\n\n### Struct in C \n\nBefore we will see the origin of everything in C, let's see the code written in C and the comments of how it would be in Golang.\nAnd we have it written in Golang, so that you can see how dynamic you were in Go, the C inheritance was simply fantastic and light.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n\nstruct Login {\n    char *User;\n    char *Email;\n};\n\n/**\n  // In Go would look like this\n  type Login struct {\n    User string\n    Email string\n  }\n */\n\nint main() {\n/** \n // In Go \nfunc main() {\n*/\n    \n    struct Login login, *pointerToLogin;\n\n    /**\n    // In Go\n    login := Login{User:\"jeffotoni\", Email:\"jef@m.com\"}\n    */\n\n    login.User = \"jeffotoni\";\n    login.Email = \"jef@m.com\";\n\n    pointerToLogin = malloc(sizeof(struct Login));\n    pointerToLogin-\u003eUser = \"pike\";\n    pointerToLogin-\u003eEmail = \"pike@g.com\";\n\n    /**\n    var pointerToLogin  = new(Login)\n    pointerToLogin.User  = \"pike\"\n    pointerToLogin.Email = \"pike@g.com\"\n    */\n    printf(\"login vals: %s %s\\n\", login.User, login.Email);\n    printf(\"pointerToLogin: %p %s %s\\n\", pointerToLogin, pointerToLogin-\u003eUser, pointerToLogin-\u003eEmail);\n\n    /**\n     fmt.Printf(\"login vals: %s %s\\n\", login.User, login.Email)\n     fmt.Printf(\"pointerToLogin: %v %s %s\\n\", pointerToLogin, pointerToLogin.User, pointerToLogin.Email);\n    */\n\n    free(pointerToLogin);\n    return 0;\n}\n```\n\nCompile the program in C:\n```\n$ gcc -o struct-1-c struct-1-c.c\n```\n\nOutput:\n```bash\nlogin vals: jeffotoni jef@m.com\npointerToLogin: 0x5627788a0260 pike pike@g.com\n```\n\nConfira agora o Código em Go abaixo:\n\n```go\npackage main\n\nimport \"fmt\"\n// #include \u003cstdio.h\u003e\n// #include \u003cstdlib.h\u003e\n\n// struct Login {\n//     char *User;\n//     char *Email;\n// };\n\n//In Go would look like this\ntype Login struct {\n    User  string\n    Email string\n}\n\n// int main() {\n\n// In Go\nfunc main() {\n\n    //struct Login login, *pointerToLogin;\n\n    // In Go\n    login := Login{User: \"jeffotoni\", Email: \"jef@m.com\"}\n\n    login.User = \"jeffotoni\"\n    login.Email = \"jef@m.com\"\n\n    // pointerToLogin = malloc(sizeof(struct Login));\n    // pointerToLogin-\u003eUser = \"pike\";\n    // pointerToLogin-\u003eEmail = \"pike@g.com\";\n\n    var pointerToLogin = new(Login)\n    pointerToLogin.User = \"pike\"\n    pointerToLogin.Email = \"pike@g.com\"\n\n    //printf(\"login vals: %s %s\\n\", login.User, login.Email);\n    //printf(\"pointerToLogin: %p %s %s\\n\", pointerToLogin, pointerToLogin-\u003eUser, pointerToLogin-\u003eEmail);\n\n    fmt.Printf(\"login vals: %s %s\\n\", login.User, login.Email)\n    fmt.Printf(\"pointerToLogin: %v %s %s\\n\", pointerToLogin, pointerToLogin.User, pointerToLogin.Email)\n\n    //free(pointerToLogin);\n    return\n}\n```\n\n```bash\nlogin vals: jeffotoni jef@m.com\npointerToLogin: \u0026{pike pike@g.com} pike pike@g.com\n```\n\n### Struct Type Tags Json\n\nWe use json tags with omitempty or not to represent our json string, when generated by **json.Marshal** which we will see soon below.\n\nExample:\n```go\nimport (\n\t//\"encoding/json\"\n\t\"fmt\"\n)\n\n// We use the omitempty tag in 'json: field, omitempty'\n// when we want the field not to appear after\n// making the marshal if it is empty.\ntype D struct {\n\tHeight int\n\tWidth  int `json:\"width,omitempty\"`\n}\n\n// Fields that do not have the \"omitempty\" tag will display \n// the same field being empty when generating \n// json through marshal.\ntype Cat struct {\n\tBreed    string `json:\"breed,omitempty\"`\n\tWeightKg int    `json:WeightKg`\n\tSize     D      `json:\"size,omitempty\"`\n}\n\nfunc main() {\n\td := Cat{\n\t\t//Breed:    \"Persa\",\n\t\tWeightKg: 23,\n\t\t//Size:     D{20, 60},\n\t}\n\t//b, _ := json.Marshal(d)\n\t//fmt.Println(string(b))\n\tfmt.Println(d)\n}\n```\n\nOutput:\n```bash\n{ 23 {20 60}}\n```\n\nIn this example we have a struct \"ApiLogin\" and inside it we have And1 \\*struct\", ie, referencing a pointer from another struct, beautiful is not.\nTo initialize and access the \"And1\" field, we have to use the \"\u0026\" operator and create the struct at its initialization because it has not been defined yet so it would look like this: **\"And1: \u0026 struct {City string} {City: \"BH\"}\"**\n```go\ntype ApiLogin struct {\n\tAnd1  *struct {\n\t\tCity string\n\t}\n}\n```\n\nIn this example we only time the pointer of a struct already defined above.\nTo access it we do not need to create it again, just refer to it with \"\u0026\" and this way \"And2: \u0026Address{}\", very nice, right?\n```go\ntype ApiLogin struct {\n\tAnd2 *Address\n}\n```\n\nThe example below is a way to display various forms of initialization using struct.\n```go\npackage main\n\nimport \"fmt\"\n\ntype Address struct {\n\tCity         string `json:\"city\"`\n\tNeighborhood string `json:\"neighborhood\"`\n\tZipcode      string `json:\"zipcode\"`\n}\n\ntype ApiLogin struct {\n\tName  string `json:\"name\"`\n\tCpf   string `json:\"cpf\"`\n\tLogin string `json:\"login\"`\n\tEmail string `json:\"email\"`\n\n\t// anonymous\n\tAnd1 *struct {\n\t\tCity string\n\t}\n\n\t// pointer\n\tAnd2 *Address\n\n\t// list Address\n\tAnd3 []Address\n}\n\nfunc main() {\n\n\t// different ways to inizialize a struct\n\t//\n\t//\n\n\tapilogin1 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And1: \u0026struct{ City string }{City: \"BH\"}}\n\tfmt.Println(apilogin1)\n\tfmt.Println(apilogin1.Name)\n\tfmt.Println(apilogin1.And1)\n\tfmt.Println(apilogin1.And1.City)\n\n\tapilogin2 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And2: \u0026Address{City: \"BH\"}}\n\tfmt.Println(apilogin2)\n\tfmt.Println(apilogin2.Name)\n\tfmt.Println(apilogin2.And2)\n\tfmt.Println(apilogin2.And2.City)\n\n\tapilogin3 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And1: \u0026struct{ City string }{City: \"BH\"}, And2: \u0026Address{City: \"BH\"}}\n\tfmt.Println(apilogin3)\n\tfmt.Println(apilogin3.Name)\n\tfmt.Println(apilogin3.And1)\n\tfmt.Println(apilogin3.And1.City)\n\tfmt.Println(apilogin3.And2)\n\tfmt.Println(apilogin3.And2.City)\n\n\tvar apilogin4 ApiLogin\n\tfmt.Println(apilogin4)\n\n\tapilogin5 := ApiLogin{}\n\tfmt.Println(apilogin5)\n\n\tapilogin6 := \u0026ApiLogin{}\n\tfmt.Println(apilogin6)\n\n\tapilogin7 := new(ApiLogin)\n\tfmt.Println(apilogin7)\n\n\t// another way to feed the struct\n\tg1add := Address{City: \"Belo Horizonte\"}\n\tg2add := Address{City: \"Curitiba\"}\n\n\t// declaring as list\n\tgall := []Address{}\n\n\t// add items\n\tgall = append(gall, g1add)\n\tgall = append(gall, g2add)\n\n\tfmt.Println(gall)\n\n\t// initializes Struct\n\tapil3 := ApiLogin{}\n\n\t// recive same type\n\tapil3.And3 = gall\n\n\t// show struct\n\tfmt.Println(apil3)\n\n\t// another way to initialize and feed the struct list\n\tapil3.And3 = []Address{{City: \"Sao Paulo\"}, {City: \"Brasilia\"}}\n\n\t// show struct\n\tfmt.Println(apil3)\n}\n```\n\nOutput:\n```bash\n\u0026{@jeffotoni 093.393.334-34   0xc00000e1e0 \u003cnil\u003e []}\n@jeffotoni\n\u0026{BH}\nBH\n\u0026{@jeffotoni 093.393.334-34   \u003cnil\u003e 0xc000060150 []}\n@jeffotoni\n\u0026{BH  }\nBH\n\u0026{@jeffotoni 093.393.334-34   0xc00000e300 0xc0000601b0 []}\n@jeffotoni\n\u0026{BH}\nBH\n\u0026{BH  }\nBH\n{    \u003cnil\u003e \u003cnil\u003e []}\n{    \u003cnil\u003e \u003cnil\u003e []}\n\u0026{    \u003cnil\u003e \u003cnil\u003e []}\n\u0026{    \u003cnil\u003e \u003cnil\u003e []}\n[{Belo Horizonte  } {Curitiba  }]\n{    \u003cnil\u003e \u003cnil\u003e [{Belo Horizonte  } {Curitiba  }]}\n{    \u003cnil\u003e \u003cnil\u003e [{Sao Paulo  } {Brasilia  }]}\n```\n\nThe example below is to demonstrate the ease we have when we manipulate structs in Golang.\nWe are initializing the struct with values and displaying on the screen.\n\nTake a look:\n```go\npackage main\n\nimport \"fmt\"\n\ntype jsoninput []struct {\n\tData string `json:\"data\"`\n}\n\nfunc main() {\n\n\tdata := \u0026jsoninput{{Data: \"some data\"}, {Data: \"some more data\"},\n\t\t{Data: \"some more data\"}}\n\tfmt.Println(data)\n\n\t// output:\n\t//  \u0026[{some data} {some more data} {some more data}]\n}\n```\n\n```bash\n\u0026[{some data} {some more data} {some more data}]\n```\n\nIn our example below is another way to make array of struct, we made the statement at the time of initializing our struct, this causes that the struct does not get caught in only accepting array of struct.\nWe did append in the fields and the magic happens.\n\nLet's take a look at the complete code:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n)\n\ntype User struct {\n\tFirstName string `tag_name:\"firstname\"`\n\tLastName  string `tag_name:\"lastname\"`\n\tAge       int    `tag_name:\"age\"`\n}\n\nfunc main() {\n\t// create instance\n\t// slice struct\n\tusers := []*User{}\n\n\tuser := new(User)\n\tuser.FirstName = \"Jefferson\"\n\tuser.LastName = \"otoni\"\n\tuser.Age = 350\n\tusers = append(users, user)\n\n\tuser = new(User)\n\tuser.FirstName = \"Pike\"\n\tuser.LastName = \"Hob\"\n\tuser.Age = 55\n\tusers = append(users, user)\n\n\tfmt.Println(users)\n\n\tfor k, v := range users {\n\t\tfmt.Println(k, v)\n\t\tfmt.Println(v.FirstName)\n\t\tfmt.Println(v.LastName)\n\t\tfmt.Println(v.Age)\n\t}\n}\n```\n\nOutput:\n```bash\n[0xc000060150 0xc000060180]\n0 \u0026{Jefferson otoni 350}\nJefferson\notoni\n350\n1 \u0026{Pike Hob 55}\nPike\nHob\n55\n```\n\nExample Struct AWS Sqs Json\n```go\ntype SqsJson struct {\n\tType      string `json:\"type\"`\n\tMessageId string `json:\"messageid\"`\n\tTopicArn  string `json:\"topicarn\"`\n\tMessage   string `json:\"message\"`\n\t//Message          JsonMessage\n\tTimestamp        string `json:\"timestamp\"`\n\tSignatureVersion string `json:\"signatureversion\"`\n\tSignature        string `json:\"signature\"`\n\tSigningCertURL   string `json:\"signingcerturl\"`\n\tUnsubscribeURL   string `json:\"unsubscribeurl\"`\n}\n\ntype JsonMessage struct {\n\tNotificationType string `json:\"notificationType\"`\n\tBounce           struct {\n\t\tBounceType        string `json:\"bounceType\"`\n\t\tBounceSubType     string `json:\"bounceSubType\"`\n\t\tBouncedRecipients []struct {\n\t\t\tEmailAddress   string `json:\"emailAddress\"`\n\t\t\tAction         string `json:\"action\"`\n\t\t\tStatus         string `json:\"status\"`\n\t\t\tDiagnosticCode string `json:\"diagnosticCode\"`\n\t\t} `json:\"bouncedRecipients\"`\n\t\tTimestamp    time.Time `json:\"timestamp\"`\n\t\tFeedbackID   string    `json:\"feedbackId\"`\n\t\tRemoteMtaIP  string    `json:\"remoteMtaIp\"`\n\t\tReportingMTA string    `json:\"reportingMTA\"`\n\t} `json:\"bounce\"`\n\n\tMail struct {\n\t\tTimestamp        time.Time `json:\"timestamp\"`\n\t\tSource           string    `json:\"source\"`\n\t\tSourceArn        string    `json:\"sourceArn\"`\n\t\tSourceIP         string    `json:\"sourceIp\"`\n\t\tSendingAccountID string    `json:\"sendingAccountId\"`\n\t\tMessageID        string    `json:\"messageId\"`\n\t\tDestination      []string  `json:\"destination\"`\n\t\tHeadersTruncated bool      `json:\"headersTruncated\"`\n\t\tHeaders          []struct {\n\t\t\tName  string `json:\"name\"`\n\t\t\tValue string `json:\"value\"`\n\t\t} `json:\"headers\"`\n\n\t\tCommonHeaders struct {\n\t\t\tFrom    []string `json:\"from\"`\n\t\t\tReplyTo []string `json:\"replyTo\"`\n\t\t\tTo      []string `json:\"to\"`\n\t\t\tSubject string   `json:\"subject\"`\n\t\t} `json:\"commonHeaders\"`\n\t} `json:\"mail\"`\n}\n```\n\nWhen the subject is struct we have several possibilities to deal with and work with this feature in Golang, it is practically embedded in everything we will build in Golang, Structs is something powerful in Go to manipulate data and send data all the time between channels using goroutine, be it in queues, database recordings, json and database reads, GraphQL, REST API, SOAP etc ...\n\n\n### Fatih Structs to Map\n\nBelow is a lib that works directly with struct, converting to Maps.\nI do not use it in production but for our course it is interesting to analyze.\nWe know that the more native we are in Golang it will be a good option, but at times we will need some libs to help us.\nThis project is not maintained anymore and is archived. Feel free to fork and make your own changes if needed.\n\nStructs contains various utilities to work with Go (Golang) structs. It was initially used by me to convert a struct into a map[string]interface{}. With time I've added other utilities for structs. It's basically a high level package based on primitives from the reflect package. Feel free to add new functions or improve the existing code.\n\nInstall\n```go\ngo get github.com/fatih/structs\n```\n\nTo test low rotate the code below:\n```go\n\ntype Server struct {\n\tName        string `json:\"name,omitempty\"`\n\tID          int\n\tEnabled     bool\n\tUsers       []string // not exported\n\thttp.Server          // embedded\n}\n\nfunc main() {\n\n\t// Create a new struct type:\n\n\tserver := \u0026Server{\n\t\tName:    \"gopher\",\n\t\tID:      12345678,\n\t\tUsers:   []string{\"jeffotoni\", \"pike\", \"dennis\", \"ken\"},\n\t\tEnabled: true,\n\t}\n\n\t// struct\n\tfmt.Println(server)\n\n\t// create struct fatih\n\ts := structs.New(server)\n\tm := s.Map() // Get a map[string]interface{}\n\tfmt.Println(m)\n\n\tv := s.Values() // Get a []interface{}\n\tfmt.Println(v)\n\n\tf := s.Fields() // Get a []*Field\n\tfmt.Println(f)\n\n\tn := s.Names() // Get a []string\n\tfmt.Println(n)\n\n\tname := s.Field(\"Name\") // Get a *Field based on the given field name\n\n\t// Get the underlying value,  value =\u003e \"gopher\"\n\tvalue := name.Value().(string)\n\tfmt.Println(value)\n\n\ttagValue := name.Tag(\"json\")\n\tfmt.Println(tagValue)\n\n\tf1, ok := s.FieldOk(\"Name\") // Get a *Field based on the given field name\n\tfmt.Println(f1, ok)\n\n\tn2 := s.Name() // Get the struct name\n\tfmt.Println(n2)\n\n\th := s.HasZero() // Check if any field is uninitialized\n\tfmt.Println(h)\n}\n```\n\nOutput:\n```bash\n\u0026{gopher 12345678 true [jeffotoni pike dennis ken] \n{ \u003cnil\u003e \u003cnil\u003e 0s 0s 0s 0s 0 map[] \u003cnil\u003e \u003cnil\u003e 0 0 {{0 0} 0} \u003cnil\u003e {0 0} map[] map[] \u003cnil\u003e []}}\nmap[Server:map[TLSConfig:\u003cnil\u003e ReadHeaderTimeout:0s IdleTimeout:0s Addr: Handler:\u003cnil\u003e \n]MaxHeaderBytes:0 TLSNextProto:map[] ConnState:\u003cnil\u003e ErrorLog:\u003cnil\u003e ReadTimeout:0s WriteTimeout:0s] \nName:gopher ID:12345678 Enabled:true Users:[jeffotoni pike dennis ken]]\n[gopher 12345678 true [jeffotoni pike dennis ken]  \u003cnil\u003e \u003cnil\u003e 0s 0s 0s 0s 0 map[] \u003cnil\u003e \u003cnil\u003e]\n[0xc000106000 0xc000106090 0xc000106120 0xc0001061b0 0xc000106240]\n[Name ID Enabled Users Server]\ngopher\nname,omitempty\n\u0026{{0x626180 0xc0000f6000 408} {Name  0x626180 json:\"name,omitempty\" 0 [0] false} structs} true\nServer\ntrue\n```\n\n### Map Types\n\nA map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type. The value of an uninitialized map is nil.\n\n```bash\nMapType     = \"map\" \"[\" KeyType \"]\" ElementType .\nKeyType     = Type .\n```\n\nThe comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice. If the key type is an interface type, these comparison operators must be defined for the dynamic key values; failure will cause a run-time panic.\n\n```bash\nmap[string]int\nmap[*T]struct{ x, y float64 }\nmap[string]interface{}\n```\n\nThe number of map elements is called its length. For a map m, it can be discovered using the built-in function len and may change during execution. Elements may be added during execution using assignments and retrieved with index expressions; they may be removed with the delete built-in function.\n\nA new, empty map value is made using the built-in function make, which takes the map type and an optional capacity hint as arguments:\n\n```bash\nmake(map[string]int)\nmake(map[string]int, 100)\n```\n\nThe initial capacity does not bound its size: maps grow to accommodate the number of items stored in them, with the exception of nil maps. A nil map is equivalent to an empty map except that no elements may be added.\n\nSome examples of map initialization:\n```go\npackage main\n\nimport \"fmt\"\n\ntype linkResult struct {\n\tbody string\n\turls []string\n}\n\ntype linkFetcher map[string]*linkResult\n\nfunc main() {\n\t// Required to initialize\n\t// the map with values\n\tvar m1 map[string]int\n\tvar m2 = make(map[string]int)\n\tvar m3 = map[string]int{\"population\": 500000}\n\tvar m4 = m3\n\tvar m5 map[string]string\n\t/* create a map*/\n\tm5 = make(map[string]string)\n\tfmt.Println(m1, m2, m3, m4, m5)\n\n\tvar l = linkFetcher{\n\t\t\"https://golang.org/\": \u0026linkResult{\n\t\t\t\"The Go Programming Language\",\n\t\t\t[]string{\n\t\t\t\t\"https://golang.org/pkg/\",\n\t\t\t\t\"https://golang.org/cmd/\",\n\t\t\t},\n\t\t},\n\t\t\"https://golang.org/pkg/\": \u0026linkResult{\n\t\t\t\"Packages\",\n\t\t\t[]string{\n\t\t\t\t\"https://golang.org/\",\n\t\t\t\t\"https://golang.org/cmd/\",\n\t\t\t\t\"https://golang.org/pkg/fmt/\",\n\t\t\t\t\"https://golang.org/pkg/os/\",\n\t\t\t},\n\t\t}}\n\n\tfmt.Println(l)\n}\n```\nOutput:\n```bash\nmap[] map[] map[population:500000] map[population:500000] map[]\n```\n\nA map is declared using the following syntax:\n```go\nvar m map[KeyType]ValueType\n\n// For example, Here is how you can declare a map of string keys to int values\nvar m map[string]int\n```\n\nThe zero value of a map is nil. A nil map has no keys. Moreover, any attempt to add keys to a nil map will result in a runtime error.\n\nLet’s see an example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Required to initialize\n\t// the map with values\n\tvar m map[string]int\n\tfmt.Println(m)\n\tif m == nil {\n\t\tfmt.Println(\"is nil\")\n\t}\n\t// Attempting to add keys\n\t// to a nil map will result in a runtime error\n\t//m[\"population\"] = 500000\n\t//fmt.Println(m)\n}\n```\n\nOutput:\n```bash\nmap[]\nis nil\n```\n\nYou can initialize a map using the built-in make() function. You just need to pass the type of the map to the make() function as in the example below. The function will return an initialized and ready to use map.\n\n```go\n// Initializing a map using the built-in make() function\nvar m = make(map[string]int)\n```\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Required to initialize\n\t// the map with values\n\tvar m = make(map[string]int)\n\tfmt.Println(m)\n\tif m == nil {\n\t\tfmt.Println(\"is nil\")\n\t}\n\tm[\"population\"] = 500000\n\tfmt.Println(m)\n}\n```\nOutput:\n```bash\nmap[]\nmap[population:500000]\n```\n\nThe example below introduces the creation of a map getting a struct done.\nWhen do we use an empty struct?\nThere are some scenarios when we have a large amount of access in our API, but when I say large is\u003e 10k = 10k of requests per second, in this scenario when we do our handler, we can implement a channel receiving an empty struct {} so that we can get put on a channel and process everything in with more security.\nWe will show more ahead this very legal approach.\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := \"key\"\n\tseen := make(map[string]struct{}) // set of strings\n\t// ...\n\tif _, ok := seen[s]; !ok {\n\t\tseen[s] = struct{}{}\n\t\t// ...first time seeing s...\n\t}\n\tfmt.Println(seen)\n}\n```\n\nOutput:\n```go\nmap[key:{}]\n```\n\nwe can also make our map key receive an empty struct.\nWell we know that it gets any type ie the struct can be complete without it's done too.\n\nExample:\n```go\ntype T struct{}\n\nfunc main() {\n\ts := T{}\n\tseen := make(map[struct{}]struct{}) // set of strings\n\t// ...\n\tif _, ok := seen[s]; !ok {\n\t\tseen[s] = struct{}{}\n\t\t// ...first time seeing s...\n\t}\n\tfmt.Println(seen)\n}\n```\n\nOutput:\n```go\nmap[{}:{}]\n```\n\n### Map Literals Continued\n\nA map literal is a very convenient way to initialize a map with some data. You just need to pass the key-value pairs separated by colon inside curly braces.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar m = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n\n\tfmt.Println(m)\n}\n```\n\nOutput:\n```bash\nmap[Italy:Roma France:Paris Japan:Toquio Brasil:Brasilia EUA:Washington, D.c]\n```\n\nSo you can check for the existence of a key in a map by using the following two-value assignment.\nThe boolean variable ok will be true if the key exists, and false otherwise.\n\n```go\nvalue, ok := m[key]\n```\n\nConsider the following map for example:\n```go\nvar C = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n```\n\n```go\ncapital, ok := C[\"EUA\"]  // \"Washington, D.c\", true\n```\n\nHowever, If you try to access a key that doesn’t exist, then the map will return an empty string \"\" (zero value of strings), and false\n\n```go\ncapital, ok := C[\"África do Sul\"]  // \"\", false\n```\n\nYou can delete a key from a map using the built-in delete() function. The syntax looks like this.\n\n```go\n// Delete the `key` from the `map`\ndelete(map, key)\n```\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar country = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n\tdelete(country, \"Japan\")\n\tdelete(country, \"Italy\")\n\tfmt.Println(country)\n}\n```\n\nOutput:\n```bash\nmap[Brasil:Brasilia EUA:Washington, D.c France:Paris]\n```\n \nIf the top-level type is just a type name, you can omit it from the elements of the literal. \n```go\npackage main\n\nimport \"fmt\"\n\ntype Login struct {\n\tUser, Login, Email string\n}\n\n// passing a struct as parameter\n// for our struct map\nvar m = map[string]Login{\n\t\"jeffotoni\": {\"jeffotoni\", \"jeff\", \"jeff@gm.com\"},\n\t\"Google\":    {\"root\", \"super\", \"google@gm.com\"},\n}\n\nfunc main() {\n\tfmt.Println(m)\n}\n```go\n\n```bash\nmap[jeffotoni:{jeffotoni jeff jeff@gm.com} Google:{root super google@gm.com}]\n```\n\n### Channel Types\n\nA channel provides a mechanism for concurrently executing functions to communicate by sending and receiving values of a specified element type. The value of an uninitialized channel is nil.\n\n```bash\nChannelType = ( \"chan\" | \"chan\" \"\u003c-\" | \"\u003c-\" \"chan\" ) ElementType .\n```\n\nThe optional \u003c- operator specifies the channel direction, send or receive. If no direction is given, the channel is bidirectional. A channel may be constrained only to send or only to receive by conversion or assignment.\n\n```bash\nchan T          // can be used to send and receive values of type T\nchan\u003c- float64  // can only be used to send float64s\n\u003c-chan int      // can only be used to receive ints\n```\n\nThe \u003c- operator associates with the leftmost chan possible:\n\n```bash\nchan\u003c- chan int    // same as chan\u003c- (chan int)\nchan\u003c- \u003c-chan int  // same as chan\u003c- (\u003c-chan int)\n\u003c-chan \u003c-chan int  // same as \u003c-chan (\u003c-chan int)\nchan (\u003c-chan int)\n```\n\nA new, initialized channel value can be made using the built-in function make, which takes the channel type and an optional capacity as arguments:\n\n```bash\nmake(chan int, 100)\n```\n\nThe capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.\n\nA channel may be closed with the built-in function close. The multi-valued assignment form of the receive operator reports whether a received value was sent before the channel was closed.\n\nA single channel may be used in send statements, receive operations, and calls to the built-in functions cap and len by any number of goroutines without further synchronization. Channels act as first-in-first-out queues. For example, if one goroutine sends values on a channel and a second goroutine receives them, the values are received in the order sent.\n\nLet me show you an example:\n```go\n\npackage main\n\nimport (\n  \"fmt\"\n  \"os\"\n  \"time\"\n)\n\ntype Promise struct {\n  Result chan string\n  Error  chan error\n}\n\nvar (\n  ch1  = make(chan *Promise)  // received a pointer from the structure\n  ch2  = make(chan string, 1) // allows only 1 channels\n  ch3  = make(chan int, 2)    // allows only 2 channels\n  ch4  = make(chan float64)   // has not been set can freely receive\n  ch5  = make(chan []byte)    // by default the capacity is 0\n  ch6  = make(chan bool, 1)   // non-zero capacity\n  ch7  = make(chan time.Time, 2)\n  ch8  = make(chan struct{}, 2)\n  ch9  = make(chan struct{})\n  ch10 = make(map[string](chan int)) // map channel\n  ch11 = make(chan error)\n  ch12 = make(chan error, 2)\n  // receives a zero struct\n  ch14 \u003c-chan struct{}\n  ch15 = make(\u003c-chan bool)          // can only read from\n  ch16 = make(chan\u003c- []os.FileInfo) // // can only write to\n  // holds another channel as its value\n  ch17 = make(chan\u003c- chan bool) // // can read and write to\n)\n\n// Parameters of Func\n// (jobs \u003c-chan int, results chan\u003c- int)\n\n// Receives Value, only read\n// jobs \u003c-chan int //receives the value\n\n// Receives Channel, only write\n// results chan\u003c- int // receive channel\n// or\n// results chan int // receive channel\n\n// Receives Channel variadic\n// results ...\u003c-chan int\n\nfunc main() {\n\n  ch2 \u003c- \"okay\"\n  defer close(ch2)\n  fmt.Println(ch2, \u0026ch2, \u003c-ch2)\n\n  ch7 \u003c- time.Now()\n  ch7 \u003c- time.Now()\n  fmt.Println(ch7, \u0026ch7, \u003c-ch7)\n  fmt.Println(ch7, \u0026ch7, \u003c-ch7)\n  defer close(ch7)\n\n  ch3 \u003c- 1 // okay\n  ch3 \u003c- 2 // okay\n  // deadlock\n  // ch3 \u003c- 3 // does not accept any more values, if you do it will error : deadlock\n  defer close(ch3)\n  fmt.Println(ch3, \u0026ch3, \u003c-ch3)\n  fmt.Println(ch3, \u0026ch3, \u003c-ch3)\n\n  ch10[\"lambda\"] = make(chan int, 2)\n  ch10[\"lambda\"] \u003c- 100\n  defer close(ch10[\"lambda\"])\n  fmt.Println(\u003c-ch10[\"lambda\"])\n}\n```\n\nOutput:\n```bash\n0xc000056180 0x55bb00 okay\n0xc0000561e0 0x55bb28 2019-01-25 15:11:41.982906669 -0200 -02 m=+0.000147197\n0xc0000561e0 0x55bb28 2019-01-25 15:11:41.982906922 -0200 -02 m=+0.000147409\n0xc00001e0e0 0x55bb08 1\n0xc00001e0e0 0x55bb08 2\n100\n```\n\n### Blank Identifier\n\nThe blank identifier is represented by the underscore character **_**. It serves as an anonymous placeholder instead of a regular (non-blank) identifier and has special meaning in declarations, as an operand, and in assignments.\n\nExample:\n```bash\n// function statement\nfunc f() (int, string, error)\n\n// function return\n_, _, _ := f()\n```\n\n### Interface Types\n\n**An interface is two things:**\n - it is a set of methods\n - but it is also a type\n\nThe __interface{} type__, the empty interface is the interface that has __no methods__\n\nSince there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface.\nThat means that if you write a function that takes an interface{} value as a parameter, you can supply that function with any value.\n\nExample:\n```go\nfunc DoSomething(v interface{}) {\n   // ...\n}\n\nvar Msg interface{}\n\ntype Stringer interface {\n    String() string\n}\n```\n\n### Here's an interface as a method\n\nAn interface type specifies a method set called its interface. A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface. The value of an uninitialized variable of interface type is nil.\n\n\n```bash\nInterfaceType      = \"interface\" \"{\" { MethodSpec \";\" } \"}\" .\nMethodSpec         = MethodName Signature | InterfaceTypeName .\nMethodName         = identifier .\nInterfaceTypeName  = TypeName .\n```\n\nAs with all method sets, in an interface type, each method must have a unique non-blank name.\n\n```go\n// A simple File interface\ninterface {\n  Read(b Buffer) bool\n  Write(b Buffer) bool\n  Close()\n}\n```\n\nMore than one type may implement an interface. For instance, if two types S1 and S2 have the method set\n\n```bash\nfunc (p T) Read(b Buffer) bool { return … }\nfunc (p T) Write(b Buffer) bool { return … }\nfunc (p T) Close() { … }\n```\n\n(where T stands for either S1 or S2) then the File interface is implemented by both S1 and S2, regardless of what other methods S1 and S2 may have or share.\n\nA type implements any interface comprising any subset of its methods and may therefore implement several distinct interfaces. For instance, all types implement the empty interface:\n\n```bash\ninterface{}\n```\n\nSimilarly, consider this interface specification, which appears within a type declaration to define an interface called Locker:\n\n```go\ntype Locker interface {\n  Lock()\n  Unlock()\n}\n```\n\nIf S1 and S2 also implement\n\n```bash\nfunc (p T) Lock() { … }\nfunc (p T) Unlock() { … }\n```\n\nthey implement the Locker interface as well as the File interface.\n\nAn interface T may use a (possibly qualified) interface type name E in place of a method specification. This is called embedding interface E in T; it adds all (exported and non-exported) methods of E to the interface T.\n\n```go\ntype ReadWriter interface {\n  Read(b Buffer) bool\n  Write(b Buffer) bool\n}\n\ntype File interface {\n  ReadWriter  // same as adding the methods of ReadWriter\n  Locker      // same as adding the methods of Locker\n  Close()\n}\n\ntype LockedFile interface {\n  Locker\n  File        // illegal: Lock, Unlock not unique\n  Lock()      // illegal: Lock not unique\n}\n```\n\nAn interface type T may not embed itself or any interface type that embeds T, recursively.\n```go\n// illegal: Bad cannot embed itself\ntype Bad interface {\n  Bad\n}\n\n// illegal: Bad1 cannot embed itself using Bad2\ntype Bad1 interface {\n  Bad2\n}\ntype Bad2 interface {\n  Bad1\n}\n```\n\nExample: \n```go\npackage main\n\nimport (\n  \"fmt\"\n)\n\ntype R struct {\n  R string\n}\n\ntype Iread interface {\n  Read() string\n}\n\nfunc (r *R) Read() string {\n  return fmt.Sprintf(\"Only: call Read\")\n}\n\nfunc Call(ir Iread) string {\n  return fmt.Sprintf(\"Read: %s\", ir.Read())\n}\n\nfunc main() {\n  var iread Iread\n  r := R{\"hello interface\"}\n  // A way to use Interface\n  iread = \u0026r\n  fmt.Println(iread, r)\n  fmt.Println(iread.Read())\n\n  // Second way to access interface\n  r2 := R{\"hello interface call\"}\n  fmt.Println(Call(\u0026r2))\n}\n```\n\nOutput:\n```bash\n\u0026{hello interface} {hello interface}\nOnly: call Read\nRead: Only: call Read\n```\n\n###  Interface as type\n\nInterfaces as type __interface{}__ means you can put value of any type, including your own custom type. All types in Go satisfy an empty interface (interface{} is an empty interface).\nIn your example, Msg field can have value of any type. \n\n\n```go\nvar val interface{} // element type of m is assignable to val\n``` \n\n```go\ntype Empty interface {\n    /* it has no methods */\n}\n\n// Because, Empty interface has no methods, \n// following types satisfy the Empty interface\nvar a Empty\n\na = 60\na = 10.5\na = \"Lambda Man\"\n```\n\nInterfaces as types looks at another example below:\n```go\npackage main\n\nimport (\n  \"fmt\"\n)\n\ntype MyStruct struct {\n  Msg interface{}\n}\n\nfunc main() {\n  b := MyStruct{}\n  // string\n  b.Msg = \"5\"\n  fmt.Printf(\"%#v %T \\n\", b.Msg, b.Msg) // Output: \"5\" string\n\n  // int\n  b.Msg = 5\n  fmt.Printf(\"%#v %T\", b.Msg, b.Msg) //Output:  5 int\n\n  // map\n  b.Msg = map[string]string{\"population\": \"500000\", \"language\": \"sueco\"}\n  fmt.Printf(\"%#v %T\", b.Msg, b.Msg) //Output:  5 int\n}\n```\n\n### Exercise One\nExercise:\nFill in the struct JsonMessage AWS above, initialize the struct and fill in the fields, and make a fmt.Println to display the filled fields.\nTo be more readable you can separate into each struct type struct.\n\n### Control Structures\n---\n\n### Control\n\nThe control structures are:\n\n__For, If, else, else if__\n\nAnd some statments between them: __break, continue, switch, case and goto__.\n\n### Control Return\n\nStatements control execution.\n\n```bash\nStatement =\n  Declaration | LabeledStmt | SimpleStmt |\n  GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |\n  FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |\n  DeferStmt .\n\nSimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .\n```\n\nA terminating statement prevents execution of all statements that lexically appear after it in the same block. The following statements are terminating:\n\n1. A \"return\" or \"goto\" statement.\n\nReturn:\n```go\npackage main\n\nfunc main() {\n  println(Lambda())\n  return\n}\n\nfunc Lambda() string {\n\n  return \"Lambda\"\n}\n```\n\nOutput:\n```bash\nLambda\n```\n\n### Control Goto\n\nGoto:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  n := 0\n\nLOOP1:\n  n++\n  if n == 10 {\n    println(\"fim\")\n    return\n  }\n\n  if n%2 == 0 {\n    goto LOOP2\n  } else {\n\n    fmt.Println(\"n\", n, \"LOOP1 here...\")\n    goto LOOP1\n  }\n\nLOOP2:\n  fmt.Println(\"n\", n, \"LOOP2 here...\")\n  goto LOOP1\n\n}\n```\n\nOutput:\n```bash\nn 1 LOOP1 here...\nn 2 LOOP2 here...\nn 3 LOOP1 here...\nn 4 LOOP2 here...\nn 5 LOOP1 here...\nn 6 LOOP2 here...\nn 7 LOOP1 here...\nn 8 LOOP2 here...\nn 9 LOOP1 here...\nfim\n```\n\n### Control if Else\n\n2. An \"if\" statement in which:\n      - the \"else\" branch is present, and\n      - both branches are terminating statements.\n```go\npackage main\n\nfunc main() {\n  n := 100\n  if n \u003e 0 \u0026\u0026 n \u003c= 55 {\n    println(\"n \u003e 0 or n \u003c= 55\")\n  } else if n \u003e 56 \u0026\u0026 n \u003c 70 {\n    println(\"n \u003e 56 and n \u003c 70\")\n  } else {\n\n    if n \u003e= 100 {\n      println(\" else here.. n \u003e 100\")\n    } else {\n      println(\" else here.. n \u003e 70\")\n    }\n  }\n}\n```\n\nOutput:\n```bash\nelse here.. n \u003e 100\n```\n\n### Control For Break Continue\n\n3. A \"for\" statement in which:\n      - there are no \"break\" statements referring to the \"for\" statement, and\n      - the loop condition is absent.\n      - there are \"continue\"\n      - A \"break\" statement terminates execution of the innermost \"for\", \"switch\", or \"select\" statement within the same \n\n```go\npackage main\n\nfunc main() {\n  // will be looping infinitely\n  // for {\n  // }\n\n  // will run only once and exit\n  for {\n    break\n  }\n\n  n := 5\n  for n \u003e 0 {\n    n--\n    println(n)\n  }\n  // Output:\n  // 4\n  // 3\n  // 2\n  // 1\n  // 0\n\n  // declaring i no and increasing i\n  for i := 0; i \u003c 5; i++ {\n    println(i)\n  }\n  // Output:\n  // 0\n  // 1\n  // 2\n  // 3\n  // 4\n\n  n = 5\n  for i := 0; i \u003c n; i++ {\n    if i \u003c= 2 {\n      continue\n    } else {\n      println(\"i \u003e 2 = \", i)\n    }\n  }\n\n  // Output:\n  // i \u003e 2 =  3\n  // i \u003e 2 =  4\n\n  n = 5\n  for i := 0; i \u003c n; i++ {\n    if i == 2 {\n      break\n    } else {\n      println(\"i: \", i)\n    }\n  }\n  // Output:\n  // i:  0\n  // i:  1\n  \n  // infinitely\n  for ; ; i++ {\n    println(\"i: \", i)\n  }\n  // Output:\n  // i:  1\n  // i:  2\n  // ..\n  // ..\n}\n```\n\n### Control Switch Case Break\n\n4. A \"switch\" statement in which:\n      - there are no \"break\" statements referring to the \"switch\" statement,\n      - there is a default \"case\", and\n      - the statement lists in each case, including the default, end in a terminating statement, or a possibly labeled \"fallthrough\" statement.\n\n```go\npackage main\n\nfunc main() {\n  j := 10\n  i := 0\n  switch j {\n  case 11:\n    println(\"here: 11\")\n    break\n  default:\n    println(\"here default\")\n    break\n  }\n\n  // infinitely\n  for ; ; i++ {\n\n    switch i {\n    case 5:\n      goto LABELS\n    case i:\n      println(\"i: \", i)\n      break\n    default:\n      println(\"default: \", i)\n    }\n  }\n\nLABELS:\n  f()\n\n}\n\nfunc f() {\n  println(\"goto fim\")\n}\n```\n\nOutput:\n```bash\nhere default\ni:  0\ni:  1\ni:  2\ni:  3\ni:  4\ngoto fim\n```\n\n### Control Label\n\n5. A labeled statement labeling a terminating statement.\n\n```go\npackage main\n\nfunc main() {\n  i := 0\n  // infinitely\n  for ; ; i++ {\n    for {\n      if i == 10 {\n        goto LABEL\n      }\n      i++\n    }\n  }\n\nLABEL:\n  f(i)\n\n}\n\nfunc f(i int) {\n  println(\"label fim i:\", i)\n}\n```\n\nOutput:\n```bash\nlabel fim i: 10\n```\n\nAll other statements are not terminating.\n\nA statement list ends in a terminating statement if the list is not empty and its final non-empty statement is terminating. \n\nA \"for\" statement with a \"range\" clause iterates through all entries of an array, slice, string or map, or values received on a channel. For each entry it assigns iteration values to corresponding iteration variables if present and then executes the block. \n\n```bash\nRangeClause = [ ExpressionList \"=\" | IdentifierList \":=\" ] \"range\" Expression .\n```\n\n### Control Range\n\nThe expression on the right in the \"range\" clause is called the range expression, which may be an array, pointer to an array, slice, string, map, or channel permitting receive operations. As with an assignment, if present the operands on the left must be addressable or map index expressions; they denote the iteration variables. If the range expression is a channel, at most one iteration variable is permitted, otherwise there may be up to two. If the last iteration variable is the blank identifier, the range clause is equivalent to the same clause without that identifier. \n\n```bash\nRange expression                          1st value          2nd value\n\narray or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E\nstring          s  string type            index    i  int    see below  rune\nmap             m  map[K]V                key      k  K      m[k]       V\nchannel         c  chan E, \u003c-chan E       element  e  E\n```\n\nSee an example below, with various uses using Range:\n```go\n\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n  // string arrays / slice\n  var lang = [...]string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n\n  // screen list\n  fmt.Println(lang)\n\n  // list the positions srtring arrays\n  for k, v := range lang {\n    fmt.Println(k, v)\n  }\n\n  /* create a map*/\n  countryCapitalMap := map[string]string{\"Brasil\": \"Brasilia\", \"EUA AMERICA\": \"Washington, D.C.\", \"France\": \"Paris\", \"Italy\": \"Roma\", \"Japan\": \"Tokyo\"}\n\n  /* print map using key-value*/\n  for country, capital := range countryCapitalMap {\n    fmt.Println(\"Capital of\", country, \"is\", capital)\n  }\n\n  // channel\n  jobs := make(chan int, 3)\n\n  // for channel\n  for j := 1; j \u003c= 3; j++ {\n    jobs \u003c- j\n  }\n  // println(\u003c-jobs)\n  // println(\u003c-jobs)\n  // println(\u003c-jobs)\n\n  // close\n  /* date is required for range to work*/\n  close(jobs)\n\n  /* This syntax is valid too. */\n  for range jobs {\n  }\n\n  /* it is mandatory to close the channels to be able to scroll */\n  for ch := range jobs {\n    println(ch)\n  }\n\n  // it is not an array struct, it will range from error.\n  sa := struct{ nick string }{\"@jeffotoni\"}\n  fmt.Println(sa.nick)\n\n  // here the range will be able to list all struct\n  a := []struct{ nick string }{{\"@devopsbr\"}, {\"@go_br\"}, {\"@awsbrasil\"}, {\"@go_br\"}, {\"@devopsbh\"}}\n  for i, v := range a {\n    fmt.Println(i, v.nick)\n  }\n\n  // struct pointer\n  var testdata *struct {\n    a *[3]int\n  }\n  for i := range testdata.a {\n    // testdata.a is never evaluated; len(testdata.a) is constant\n    // i ranges from 0 to 2\n    fmt.Println(i)\n  }\n\n  // new example interface and range\n  var key string\n  var val interface{} // element type of m is assignable to val\n  m := map[string]int{\"mon\": 0, \"tue\": 1, \"wed\": 2, \"thu\": 3, \"fri\": 4, \"sat\": 5, \"sun\": 6}\n  for key, val = range m {\n    fmt.Println(key, val)\n  }\n}\n```\n\nOutput:\n```bash\n[Erlang Elixir Haskell Clojure Scala]\n0 Erlang\n1 Elixir\n2 Haskell\n3 Clojure\n4 Scala\nCapital of Brasil is Brasilia\nCapital of EUA AMERICA is Washington, D.C.\nCapital of France is Paris\nCapital of Italy is Roma\nCapital of Japan is Tokyo\n@jeffotoni\n0 @devopsbr\n1 @go_br\n2 @awsbrasil\n3 @go_br\n4 @devopsbh\n0\n1\n2\nsat 5\nsun 6\nmon 0\ntue 1\nwed 2\nthu 3\nfri 4\n```\n### Errors\n---\n \n The predeclared type error is defined as \n\n ```bash\n type error interface {\n\tError() string\n}\n ```\nIt is the conventional interface for representing an error condition, with the nil value representing no error. For instance, a function to read data from a file might be defined: \n\n```bash\nfunc Read(f *File, b []byte) (n int, err error)\n```\n\n### Introduction Errors\n\nError handling in Golang is very simple to deal with. There is no try, catch or exceptions.\nThe error is handled with every call of some function.\nAs we show \"error\" is an interface, and much used.\n\nWhen we talk about handling errors in Golang everything is very simple, a good practice is to return an error in the functions that we created and treat them.\n\nLet's see in practice how it works.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar error error\n\tfmt.Println(error)\n}\n```\n\nOutput:\n```bash\n\u003cnil\u003e\n```\n### How Error Control Works\n\nExample:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nvar Error error\nvar b []byte\n\nfunc main() {\n\tfmt.Println(Error)\n\tcpu := make(chan int)\n\t// Create JSON from the instance data.\n\tb, Error = json.Marshal(cpu)\n\tif Error != nil {\n\t\tfmt.Println(Error)\n\t} else {\n\t\tfmt.Println(string(b))\n\t}\n}\n```\n\nOutput:\n```bash\n\u003cnil\u003e\njson: unsupported type: chan int\n```\n\n### Errors New\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\nfunc Sqrt(fvalue float64) (float64, error) {\n\tif fvalue \u003c 0 {\n\t\treturn 0, errors.New(\"Math: negative number passed to Sqrt [\" + fmt.Sprintf(\"%.2f\", fvalue) + \"]\")\n\t}\n\treturn math.Sqrt(fvalue), nil\n}\n\nfunc main() {\n\tresult, err := Sqrt(-33)\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(\"Sqrt (-33) = [\", result, \"]\")\n\t}\n\n\tresult, err = Sqrt(81)\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(\"Sqrt(81) = [\", result, \"]\")\n\t}\n}\n```\nOutput:\n```bash\nMath: negative number passed to Sqrt [-33.00]\nSqrt(81) = [ 9 ]\n```\n\n### Custom Errors\n\n```go\npackage main\n\nimport \"fmt\"\n\n// It's possible to use custom types as `error`s by\n// implementing the `Error()` method on them.\ntype MyError struct {\n    line int\n    msg  string\n}\n\nfunc (e *MyError) Error() string {\n    return fmt.Sprintf(\"%d - %s\", e.line, e.msg)\n}\n\nfunc MyFunc(line int) (int, error) {\n    if line \u003c 100 {\n\n        // In this case we use `\u0026MyError` syntax to build\n        // a new struct, supplying values for the two\n        // fields `arg` and `prob`.\n        return -1, \u0026MyError{line, \"can't work with it\"}\n    }\n    return line, nil\n}\n\nfunc main() {\n\n    // The one loops below test out each of our\n    // error-returning functions.\n    for _, i := range []int{200, 99} {\n        if r, e := MyFunc(i); e != nil {\n            fmt.Println(\"MyFunc failed:\", e)\n        } else {\n            fmt.Println(\"MyFunc worked in line: \", r)\n        }\n    }\n}\n```\n\nOutput:\n```bash\nMyFunc worked in line:  200\nMyFunc failed: 99 - can't work with it\n```\n\n### fmt Errorf\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"math\"\n)\n\nfunc circleArea(radius float64) (float64, error) {\n    if radius \u003c 0 {\n        return 0, fmt.Errorf(\"Failed, radius %0.2f is less than zero\", radius)\n    }\n    return math.Pi * radius * radius, nil\n}\n\nfunc main() {\n    radius := -80.0\n    area, err := circleArea(radius)\n    if err != nil {\n        fmt.Println(err)\n        return\n    }\n    fmt.Printf(\"Area of circle: %0.2f\", area)\n}\n```\nOutput:\n```bash\nArea calculation failed, radius -80.00 is less than zero\n```\n\n### Functions \n---\n\nDeclaring and Calling Functions in Golang. \nIn Golang, we declare a function using the func keyword. \nA function has a name, a list of comma-separated input parameters along with their types, the result type(s), and a body. \nThe input parameters and return type(s) are optional for a function.\n\nExample of declaring and Calling Functions in Golang:\n```go\nfunc Sum(x float64, y float64) float64 {\n\treturn (x + y) / 2\n}\n```\n\n### Introduction Function\n\nGo requires explicit returns, i.e. it won’t automatically return the value of the last expression.\nWhen you have multiple consecutive parameters of the same type, you may omit the type name for the like-typed parameters up to the final parameter that declares the type.\nA function type denotes the set of all functions with the same parameter and result types. The value of an uninitialized variable of function type is nil. \n\nSome possibilities:\n```bash\nfunc()\nfunc(x int) int\nfunc(a, _ int, z float32) bool\nfunc(a, b int, z float32) (bool)\nfunc(prefix string, values ...int)\nfunc(a, b int, z float64, opt ...interface{}) (success bool)\nfunc(int, int, float64) (float64, *[]int)\nfunc(n int) func(p *T)\n```\n\n```go\npackage main\n\nfunc F1(name string) string {\n    return \"Hello, \" + name\n}\n\nfunc main() {\n\n    println(F1(\"@go_br\"","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffotoni%2Fgoworkshopdevops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffotoni%2Fgoworkshopdevops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffotoni%2Fgoworkshopdevops/lists"}