{"id":21327695,"url":"https://github.com/mostafa-wael/go-guide-for-beginners","last_synced_at":"2025-09-10T12:36:44.600Z","repository":{"id":112397929,"uuid":"558347265","full_name":"Mostafa-wael/GO-Guide-for-Beginners","owner":"Mostafa-wael","description":"This is a guide for beginners to learn Go. It is a work in progress. ","archived":false,"fork":false,"pushed_at":"2022-10-27T11:24:52.000Z","size":9,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-12T07:32:16.114Z","etag":null,"topics":["go","golang","guide","programming-languages"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mostafa-wael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-10-27T11:19:43.000Z","updated_at":"2024-04-25T15:29:03.000Z","dependencies_parsed_at":"2023-05-14T12:00:19.289Z","dependency_job_id":null,"html_url":"https://github.com/Mostafa-wael/GO-Guide-for-Beginners","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Mostafa-wael/GO-Guide-for-Beginners","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mostafa-wael%2FGO-Guide-for-Beginners","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mostafa-wael%2FGO-Guide-for-Beginners/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mostafa-wael%2FGO-Guide-for-Beginners/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mostafa-wael%2FGO-Guide-for-Beginners/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mostafa-wael","download_url":"https://codeload.github.com/Mostafa-wael/GO-Guide-for-Beginners/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mostafa-wael%2FGO-Guide-for-Beginners/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274463235,"owners_count":25290113,"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","status":"online","status_checked_at":"2025-09-10T02:00:12.551Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","guide","programming-languages"],"created_at":"2024-11-21T21:19:04.079Z","updated_at":"2025-09-10T12:36:44.577Z","avatar_url":"https://github.com/Mostafa-wael.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GO Guide for Beginners\n![logo](https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Go_Logo_Blue.svg/1200px-Go_Logo_Blue.svg.png)\n\nThis is a guide for beginners to learn Go. It is a work in progress. If you have any suggestions, please open an issue or a pull request.\n\n## Table of Contents\n- [GO Guide for Beginners](#go-guide-for-beginners)\n  - [Table of Contents](#table-of-contents)\n  - [Initialize-the-Project](#initialize-the-project)\n  - [Build-and-Run](#build-and-run)\n  - [Simple-Code](#simple-code)\n  - [Variables](#variables)\n  - [Input](#input)\n  - [Arrays-and-Slices](#arrays-and-slices)\n  - [Maps](#maps)\n  - [Structs](#structs)\n  - [Loops](#loops)\n  - [Conditionals](#conditionals)\n  - [Functions](#functions)\n  - [Packages](#packages)\n    - [Example 1(Different files in the same package)](#example-1different-files-in-the-same-package)\n    - [Example 2(Different files in different packages)](#example-2different-files-in-different-packages)\n  - [Go Routines](#go-routines)\n  - [Channels](#channels)\n  - [Mutex](#mutex)\n\n## Initialize-the-Project\n```bash\ngo mod init \u003cprojectname\u003e\n# OR, a repository name\ngo mod init github.com/\u003cusername\u003e/\u003cprojectname\u003e\n```\nThis command, creates a go.mod file, which is the go module file. This file contains the dependencies of the project.\n\n## Build-and-Run\nWe build the project and run the executable file.\n```bash\ngo build main.go\n./main\n```\nWe can also compile and run the main.go file in one command.\n```bash\ngo run main.go\n```\n\n\n## Simple-Code\n```go\npackage main\nPrint(\"Hello World\")\n```\nIn GO, everything is a package. The main package is the entry point of the program. The main package is the only package that can be executed.\nActually, we should define a function called main, which is the entry point of the program.\n```go\npackage main\nfunc main() {\n    Print(\"Hello World\")\n}\n```\nThe Print function is defined in the fmt package which stands for the Format package. So, we need to import the fmt package.\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    fmt.Print(\"Hello World\")\n}\n```\nNote that, we can import multiple packages in one line and we should whatever package we have imported.\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    fmt.Println(\"Hello World\")\n}\n```\n\n## Variables\n\nTo define a variable, we use the `var` keyword. You don't need to specify the type of the variable. The compiler will infer the type of the variable.\nNote that, you will get an error if you defined a var without using it. \n```go\npackage main\nimport \"fmt\"\nfunc main() {\n\t// part 1\n\tvar name string = \"Mostafa\"\n\tfmt.Println(name)\n\t// you can also use it like\n\tfmt.Println(\"Hello\", name, \"!\")\n\n\t// part 2\n\t// const constAge int = 20           // this value can't be changed\n\tvar age int = 20                  // this value can be changed\n\tfmt.Printf(\"My age is %v\\n\", age) // use Printf and a format specifier to format your output\n\n\t// part 3\n\t// if you didn't specify a default value, you should specify the type\n\tvar isCool bool\n\tisCool = true\n\n\t// part 4\n\t// you can print the type of a variable like this:\n\tfmt.Printf(\"isCool is of type: %T\\n\", isCool)\n\n\t// part 5\n\t// you can use short hand declaration to declare a variable\n\tsize := 2.3 // use this, not that it doesn't work with types\n\t// var size float32 = 2.3 // instead of this\n}\n```\n\n## Input\n\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    var name string // you should define the variable and its type first\n    fmt.Print(\"Enter your name: \")\n    fmt.Scan(\u0026name)\n    fmt.Println(\"Hello\", name, \"!\")\n}\n```\n\n## Arrays-and-Slices \n\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    // part 1\n    // arrays\n    var fruits [2]string // you should define the size of the array\n    fruits[0] = \"Apple\"\n    fruits[1] = \"Orange\"\n    fmt.Println(fruits) // prints [Apple Orange], the whole array\n    fmt.Println(len(fruits)) // prints 2, the length of the array\n\n    // part 2\n    // slices, just arrays without a size\n    var vegetables = []string{\"Tomato\", \"Potato\"} // we can add a default value if we want, just like arrays\n    fmt.Println(vegetables) // prints [Tomato Potato], the whole array\n    fmt.Println(vegetables[1]) // prints Potato, the second element of the array\n\n    // part 3\n    // slices are dynamic\n    vegetables = append(vegetables, \"Cucumber\")\n    fmt.Println(vegetables) // prints [Tomato Potato Cucumber], the whole array\n\n    // part 4\n    // slices are reference types\n    // so, if you change a slice, you will change the original slice\n    // and if you change the original slice, you will change the other slices\n    // that are referencing to the original slice\n    var otherVegetables = vegetables // this is a reference to the original slice, otherVegetables is a pointer to vegetables\n    otherVegetables[0] = \"Onion\" // equivalent to vegetables[0] = \"Onion\"\n    fmt.Println(vegetables) // prints [Onion Potato Cucumber], the whole array\n    fmt.Println(otherVegetables) // prints [Onion Potato Cucumber], the whole array\n}\n``` \n\n## Maps\n\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    // part 1\n    // maps\n    var person = map[string]string{\"name\": \"Mostafa\", \"age\": \"22\"} // you should define the key and value types\n    fmt.Println(person) // prints map[age:22 name:Mostafa], the whole map\n    fmt.Println(person[\"name\"]) // prints Mostafa, the value of the key \"name\"\n\n    // part 2\n    // maps are dynamic\n    person[\"height\"] = \"172\" // add a new key and value\n    fmt.Println(person) // prints map[age:22 height:172 name:Mostafa], the whole map\n\n    // part 3\n    // maps are reference types\n    // so, if you change a map, you will change the original map\n    // and if you change the original map, you will change the other maps\n    // that are referencing to the original map\n    var otherPerson = person // this is a reference to the original map, otherPerson is a pointer to person\n    otherPerson[\"name\"] = \"Wael\" // equivalent to person[\"name\"] = \"Wael\"\n    fmt.Println(person) // prints map[age:22 height:172 name:Wael], the whole map\n    fmt.Println(otherPerson) // prints map[age:22 height:172 name:Wael], the whole map\n\n    // part 4\n    // Create an empty map\n    var emptyMap = make(map[string]string) // we use the make function to create an empty map\n    fmt.Println(emptyMap) // prints map[]\n    var emptyMap2 = map[string]string{} // we can also use this syntax\n    fmt.Println(emptyMap2) // prints map[]\n    var emptyMapDefaultSize = make(map[string]string, 10) // we can also specify the default size of the map\n    fmt.Println(emptyMapDefaultSize) // prints map[]\n    fmt.Println(len(emptyMapDefaultSize)) // prints 0, the length of the map\n\n    // part 5\n    // Delete a key from a map\n    delete(person, \"age\") // delete the key \"age\" from the map person\n    fmt.Println(person) // prints map[height:172 name:Wael], the whole map\n}\n```\n\n## Structs\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    // part 1\n    // structs\n    type Person struct {\n        name string\n        age int\n    }\n    var person = Person{name: \"Mostafa\", age: 22} // you should define the fields and their types\n    fmt.Println(person) // prints {Mostafa 22}, the whole struct\n    fmt.Println(person.name) // prints Mostafa, the value of the field \"name\"\n\n    // part 2\n    // structs are dynamic\n    person.age = 23 // change the value of the field \"age\"\n    fmt.Println(person) // prints {Mostafa 23}, the whole struct\n\n    // part 3\n    // structs are value types\n    // so, if you change a struct, you will change the original struct\n    // and if you change the original struct, you won't change the other structs\n    // that are referencing to the original struct\n    var otherPerson = person // this is a copy of the original struct, otherPerson is a pointer to person\n    otherPerson.name = \"Wael\" // equivalent to person.name = \"Wael\"\n    fmt.Println(person) // prints {Mostafa 23}, the whole struct\n    fmt.Println(otherPerson) // prints {Wael 23}, the whole struct\n\n    // part 4\n    // Create an empty struct\n    var emptyStruct = Person{} // we can use this syntax\n    fmt.Println(emptyStruct) // prints { 0}, the whole struct\n    var emptyStruct2 = Person{name: \"Mostafa\"} // we can also use this syntax\n    fmt.Println(emptyStruct2) // prints {Mostafa 0}, the whole struct\n}\n```\n\n\n## Loops\n    \n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    // part 1\n    // for loop\n    for i := 0; i \u003c 5; i++ {\n        fmt.Println(i)\n    }\n\n    // part 2\n    // while loop\n    var i int = 0\n    for i \u003c 5 {\n        fmt.Println(i)\n        i++\n    }\n\n    // part 3\n    // infinite loop\n    for {\n        fmt.Println(\"Hello World\")\n    }\n\n    // part 4\n    // range\n    var fruits = []string{\"Apple\", \"Orange\", \"Banana\"}\n    for index, fruit := range fruits {\n        fmt.Println(index, fruit)\n    }\n}\n```\n\n## Conditionals\n\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    // part 1\n    // if statement\n    var age int = 20\n    if age \u003e 18 {\n        fmt.Println(\"You are an adult\")\n    } else if age \u003e 12 {\n        fmt.Println(\"You are a teenager\")\n    } else {\n        fmt.Println(\"You are a child\")\n    }\n\n    // part 2\n    // switch statement\n    switch age {\n    case 18:\n        fmt.Println(\"You are 18\")\n    case 20:\n        fmt.Println(\"You are 20\")\n    default:\n        fmt.Println(\"You are not 18 or 20\")\n    }\n}\n```\n\n## Functions\n\n```go\npackage main\nimport \"fmt\"\nfunc main() {\n    // part 1\n    // function with no parameters and no return value\n    sayHello()\n\n    // part 2\n    // function with parameters and no return value\n    sayHelloTo(\"Mostafa\")\n\n    // part 3\n    // function with parameters and return value\n    var result int = sum(2, 3)\n    fmt.Println(result)\n\n    // part 4\n    // function with multiple return values\n    var sumResult, subResult int = sumAndSub(2, 3)\n    fmt.Println(sumResult, subResult)\n}\nfunc sayHello() {\n    fmt.Println(\"Hello World\")\n}\nfunc sayHelloTo(name string) {\n    fmt.Println(\"Hello\", name)\n}\nfunc sum(a int, b int) int {\n    return a + b\n}\nfunc sumAndSub(a int, b int) (int, int) {\n    return a + b, a - b\n}\n```\n\n## Packages\nIn Go, everything is a package. You can import a package and use its functions. You can also create your own package and use it in your code. \n### Example 1(Different files in the same package)\n```go\n// helper.go\npackage main\nimport \"fmt\"\nfunc SayHello() {\n    fmt.Println(\"Hello World\")\n}\n```\n```go\n// main.go\npackage main\nimport \"fmt\"\nfunc main() {\n    sayHelloTo(\"Mostafa\")\n}\n```\nSince the `helper.go` and `main.go` files are in the same package, we can use the `SayHello` function in the `main.go` file directly.\nYou can run the code using `go run main.go helper.go` or `go run .` if you are in the same directory as the files.\n### Example 2(Different files in different packages)\nWhen using different packages, you should separate the files in different directories.\n```go\n// helper/helper.go\npackage helper\nimport \"fmt\"\n// This function now, acts as a global-public- function\nfunc SayHello() {\n    fmt.Println(\"Hello World\")\n}\n```\n```go\n// main.go\npackage main\nimport(\n    \"fmt\"\n    \"guide/helper\" // we got this from the module name in go.mod\n)\n// or \n// import \"fmt\"\n// import \"guide/helper\"\nfunc main() {\n    helper.SayHello() // we should use the package name as a prefix\n}\n```\nNote, that we had to capitalize the first letter of the `SayHello` function in the `helper.go` file. This is because the function is exported and can be used in other packages. If we didn't capitalize the first letter, the function would be private and we couldn't use it in other packages. The same applies for variables and structs.\nNow, you can relate why all the functions in the `fmt` package started with a capital letter. \n\nYou can also share your package with others. You can find more information about packages [here](https://golang.org/doc/code.html).    \n\n## Go Routines\nGo Routines are lightweight threads. They are used to run multiple functions at the same time. You can use them to run multiple functions at the same time. You can also use them to run a function in the background. \n```go\npackage main\nimport (\n\t\"fmt\"\n\t\"time\"\n)\nfunc main() {\n    // part 1\n    // run a function in the background\n    go sayHello()\n    time.Sleep(1 * time.Second)\n\n    // part 2\n    // run multiple functions at the same time\n    go sayHello()\n    go sayHelloTo(\"Mostafa\")\n    time.Sleep(1 * time.Second)\n\n    // part 3\n    // run a function in the background and wait for it\n    go func() {\n        fmt.Println(\"Hello World\")\n    }()\n    time.Sleep(1 * time.Second)\n\n    // part 4\n    // run multiple functions at the same time and wait for them\n    go func() {\n        fmt.Println(\"Hello World\")\n    }()\n    go func(name string) {\n        fmt.Println(\"Hello\", name)\n    }(\"Mostafa\")\n    time.Sleep(1 * time.Second)\n}\nfunc sayHello() {\n    fmt.Println(\"Hello World\")\n}\nfunc sayHelloTo(name string) {\n    fmt.Println(\"Hello\", name)\n}\n\n```\n\n## Channels\nChannels are used to communicate between Go Routines. You can send and receive data from a channel. \n```go\npackage main\nimport (\n    \"fmt\"\n    \"time\"\n)\nfunc main() {\n    // part 1\n    // create a channel\n    var channel chan string = make(chan string)\n\n    // part 2\n    // send data to a channel\n    go func() {\n        channel \u003c- \"Hello World\"\n    }()\n\n    // part 3\n    // receive data from a channel\n    var message string = \u003c-channel\n    fmt.Println(message)\n\n    // part 4\n    // create a buffered channel\n    var bufferedChannel chan string = make(chan string, 2)\n    bufferedChannel \u003c- \"Hello\"\n    bufferedChannel \u003c- \"World\"\n    fmt.Println(\u003c-bufferedChannel)\n    fmt.Println(\u003c-bufferedChannel)\n\n    // part 5\n    // create a channel with a timeout\n    var timeoutChannel chan string = make(chan string, 1)\n    go func() {\n        time.Sleep(2 * time.Second)\n        timeoutChannel \u003c- \"Hello World\"\n    }()\n    select {\n    case message := \u003c-timeoutChannel:\n        fmt.Println(message)\n    case \u003c-time.After(1 * time.Second):\n        fmt.Println(\"Timeout\")\n    }\n}\n```\n\n## Mutex\nMutex is used to lock a variable or a function. Only one Go Routine can lock a variable or a function at a time. If another Go Routine tries to lock the same variable or function, it will be blocked until the first Go Routine unlocks the variable or function. \n```go\npackage main\nimport (\n    \"fmt\"\n    \"sync\"\n    \"time\"\n)\nfunc main() {\n    var counter int = 0\n    var wg sync.WaitGroup // used to wait for all the Go Routines to finish\n    var mutex sync.Mutex // used to lock the counter variable\n    for i := 0; i \u003c 10; i++ {\n        wg.Add(1) // acts as a counter\n        go func() {\n            mutex.Lock() // lock the counter variable\n            counter++\n            fmt.Println(counter)\n            mutex.Unlock() // unlock the counter variable\n            wg.Done() // to decrement the counter\n        }()\n    }\n    wg.Wait() // wait for all the Go Routines to finish before exiting the program\n    fmt.Println(counter)\n}\n```\n\u003e\u003e If you have any suggestions, please open an issue or a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmostafa-wael%2Fgo-guide-for-beginners","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmostafa-wael%2Fgo-guide-for-beginners","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmostafa-wael%2Fgo-guide-for-beginners/lists"}