[{"content":"","date":null,"permalink":"https://gosamples.dev/","section":"GOSAMPLES","summary":"","title":"GOSAMPLES"},{"content":"","date":null,"permalink":"https://gosamples.dev/tutorials/","section":"Tutorials","summary":"","title":"Tutorials"},{"content":"In Go, to add a new external package to your project, you must first download it. You can do this by using the built-in go get command.\nThe go get command is a tool used to download dependencies along with updating the go.mod file. It is part of the Go toolchain and comes pre-installed with the language. Using this command, you can download Go packages for your project from remote repositories such as GitHub, Bitbucket or other Git-based repositories.\nImportant note #The latest versions of the go get command work only with Go modules. It means that go get will not work if your project is not a Go module created with the go mod init command and does not have a go.mod file.\nBasic usage #Basic syntax of the go get command:\ngo get [flags] [packages] For more information on flags and package naming, check the documentation of the command using the following command in terminal:\ngo help get or on the official documentation site here. In this post we will focus on usage examples.\nExamples # Remember: Every time you run the go get command, it is also good practice to run the command:\ngo mod tidy This command ensures that the go.mod file matches the source code and cleans the go.mod and go.sum of unused and unnecessary dependencies created when upgrading packages to new versions.\nGet a package #Use go get followed by the package name to add the package to your Go module.\ngo get github.com/google/uuid Get multiple packages at once #Use space-separated package names to download multiple packages at once.\ngo get github.com/google/uuid gorm.io/gorm Update package to the latest version #To update the package to the latest version, use the explicit -u flag:\ngo get -u github.com/google/uuid You can also use the standard go get command, which also updates the package to the latest version, if available:\ngo get github.com/google/uuid Get a specific version of the package #To use a specific package version or to upgrade or downgrade a package version, use the @version query suffix:\ngo get github.com/google/uuid@v1.3.0 Update package to the latest patch version #Use -u=patch flag to update a package to the latest patch version:\ngo get -u=patch github.com/google/uuid You can also use @patch version suffix to do the same:\ngo get -u github.com/google/uuid@patch Update package to a specific revision (commit hash) #You can also get a package in a specific commit version using @revision query suffix:\ngo get -u github.com/google/uuid@ae25fc6Using query suffix @branch-or-tag-name, you can retrieve the package version from a specific branch or tag: Upgrade package to branch or tag version #Using query suffix @branch-or-tag-name, you can retrieve the package version from a specific branch or tag:\ngo get -u github.com/google/uuid@master Upgrade all packages in your module at once #If you want to update all your project\u0026rsquo;s dependencies at once, use the command:\ngo get -u ./... or:\ngo get -u all Read our post on how to update all Go packages to the latest version to learn more.\nRemove package from your module #To completely remove a dependency from a Go module, use the go get with the suffix @none. Modules that depend on the removed module will be downgraded or also removed:\ngo get github.com/google/uuid@none Where go get downloads the project’s dependencies from #By default, the go get command retrieves dependencies from two sources:\nGoogle\u0026rsquo;s managed module proxy server: https://proxy.golang.org/, and if the module is not available in the Google proxy, then from the repository whose address is specified by the module path. This behavior is specified in the GOPROXY environment variable, which you can output with go env:\ngo env GOPROXY The default output:\nhttps://proxy.golang.org,direct If you want to change the default behavior of downloading from the module proxy and instead use direct downloading of modules from repositories, you should set the environment variable, for example, with the go env -w command:\ngo env -w GOPROXY=direct First, however, it is useful to know what the module proxy is. You can read about it in the official blog post.\nUsing the same command, you can also set your own proxy servers as the source:\ngo env -w GOPROXY=https://proxy.example.com,https://proxy2.example.com,direct If you want, you can also change the default behavior in a single command only. All you need to do before the go get command is to set the GOPROXY environment variable for the execution of the command:\nGOPROXY=direct go get github.com/google/uuid Where go get puts the project\u0026rsquo;s dependencies on your local machine #The go get command downloads modules to a dedicated cache. If another project needs a module with the same version that is already in the cache, it is not fetched again but loaded from the cache. Packages are downloaded only when they are missing from the cache.\nThe default location of the module cache is $GOPATH/pkg/mod. You can check the exact path by printing the GOMODCACHE environment variable:\n$GOPATH/pkg/mod You can also change the default cache location by using the go env -w command:\ngo env -w GOMODCACHE=~/mod-cache The module cache has unlimited size and its contents are not removed automatically. But you can erase its entire contents manually with the command:\ngo clean -modcache Difference between go get and go install commands #In earlier versions of Go, there was some inconsistency regarding the exact differences between the go get and go install commands. Currently, these commands have their distinct responsibilities:\nThe go get command handles package management - adding, updating, or removing dependencies in the go.mod file. The go get does not build packages. The go install command builds the package and installs the executable file in the directory defined by the GOBIN environment variable, which defaults to the $GOPATH/bin path. Installing the executable file allows you to call it directly from your system terminal by simply typing the command name, e.g. mytool in the command line. ","date":"23 May 2023","permalink":"https://gosamples.dev/go-get/","section":"Tutorials","summary":"","title":"🏃‍♂️ What is 'go get' command in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/dictionary/","section":"Tags","summary":"","title":"Dictionary"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/go-get/","section":"Tags","summary":"","title":"Go Get"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/go-module/","section":"Tags","summary":"","title":"Go Module"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/","section":"Tags","summary":"","title":"Tags"},{"content":"As a quick reference, to upgrade the Go modules in your project, you can use the following commands:\nUse go get -u ./... if you want to update all dependencies to the latest version in the current directory and its subdirectories. Use go get -t -u ./... to update all dependencies in the current directory and its subdirectories including test dependencies. Use go get -u all if you want to update all packages in the main module and all its dependencies including test dependencies. Use go get -u to update all dependencies in the current directory only. After running the go get command, it is a good practice to also run go mod tidy. This command ensures that the go.mod file is in sync with your source code and cleans it up by removing any unused or unnecessary dependencies that may have been created after updating packages to new version. Disclaimer: Although a Go module is not exactly the same as a package, for the purposes of this article we use the terms module, package and dependency interchangeably, always referring to a Go module as a collection of packages with go.mod and go.sum files.\nUpdate all Go packages in your project at once to the latest version #Updating external packages is an important part of maintaining any application. New versions often provide bug fixes, remove security vulnerabilities, improve performance and introduce new features. However, in a project that imports many external packages, updating each package one by one can be cumbersome. In such cases, there are great commands that allow you to update all the dependencies in your project at once.\nIn Go, to do an upgrade of all packages imported by Go files in the given root directory and all its subdirectories, use the following go get command:\ngo get -u ./\u0026hellip;\nThe go get is a built-in Go command used to download and maintaing packages and dependencies in the project. If you want to know more about this command check out our blog post on What is \u0026lsquo;go get\u0026rsquo; command in Go or the official documentation.\nThe -u flag instructs the command to update the named packages and their dependencies to the latest available version.\nThe path ./... is a special pattern meaning that go get -u will be executed on the current directory as well as recursively on all its subdirectories. So as a result, by executing this command in the root of the project, all dependencies will be updated.\nWhenever you run the go get command, it is good practice to also execute: go mod tidy This command ensures that the go.mod file matches the source code and cleans the go.mod and go.sum of unused and unnecessary dependencies created when packages are upgraded to new versions.\nThe regular go get -u ./... command skips package updates in the *_test.go test files. But you can update dependencies in the test files as well by using the extra -t flag:\ngo get -t -u ./\u0026hellip;\nThere is also an alternative version of the command to update all packages in the project at once along with test dependencies:\ngo get -u all\nThis command has the same effect as the one above, but its benefit is that you do not have to call it from the project\u0026rsquo;s root directory to update all dependencies of the project. The name all means: update all packages in the main module including their dependencies and dependencies of their tests.\nUpgrade all packages to the new patch version only #To update all Go modules only to the latest patch version, use the -u=patch flag in the go get command: go get -u=patch ./\u0026hellip; or go get -u=patch all This command upgrades packages only to the latest patch version as defined in the Semantic Versioning version: MAJOR.MINOR.PATCH. It means that any changes to the minor or major versions of the package will be ignored. This is useful when you want to ensure that your project is up-to-date with the latest security patches and bug fixes, without introducing any breaking changes. By upgrading to the latest patch version regularly, you can ensure that your codebase is secure and reliable, without having to worry about compatibility issues or other problems.\nUpdate all dependencies only in the current directory #If you need to update Go packages only in the current directory, just use the command: go get -u By default, if no path is defined in the go get, the command works only in the current directory.\nList packages to update in your project #If you want to display all packages in your project together with information if they can be updated, use the command: go list -m -u all This command lists all project\u0026rsquo;s Go modules along with the version that is currently installed and the latest available version. Note that this command prints out direct dependencies, i.e. those that the project directly imports, as well as indirect dependencies, i.e. those that are required by direct dependencies. An example output:\ngithub.com/go-kit/log v0.1.0 [v0.2.1] github.com/go-stack/stack v1.8.0 [v1.8.1] github.com/google/uuid v1.3.0 As you can see in the output, the package name is followed by the current version of the package in the project, and the latest available version is placed in square brackets. This command returns all the packages in the project, so if any are up to date then the version in square brackets will not be displayed, as in the last line of the sample output.\nTo display only the direct packages (those that are directly imported by go.mod) that need updating, you should use the -f flag and prepare your own output formatting.\ngo list -u -f \u0026#39;{{if (and (not (or .Main .Indirect)) .Update)}}{{.Path}}: {{.Version}} -\u0026gt; {{.Update.Version}}{{end}}\u0026#39; -m all An example output:\ngithub.com/go-kit/log: v0.1.0 -\u0026gt; v0.2.1 github.com/go-stack/stack: v1.8.0 -\u0026gt; v1.8.1 This format indicates that if there is a non-empty Update structure in the data for direct dependencies, then the string should be displayed in the following format:\n\u0026lt;package path\u0026gt;: \u0026lt;current version\u0026gt; -\u0026gt; \u0026lt;version to update\u0026gt; The go list -m command has a lot of features so if you want to know them all, check the official documentation.\nUpdate a single package to a specific version #If your goal is to update only a single package you can do it in a variety of ways using the go get -u command with additional flags and modifiers.\nIf you want to update a single package to the latest version in Go, use go get -u with the package name: go get -u github.com/go-kit/log\nTo upgrade or downgrade a package to a specific version, use the @version suffix:\ngo get -u github.com/go-kit/log@v0.2.0 To update a Go module to a specific revision, use the @revision version query: go get -u github.com/go-kit/log@0b69c70\nTo get a specific branch or tag version of the package use the @branch or @tag version query: go get -u github.com/go-kit/log@main\nUpgrade a single package only to a new patch version #As with updating all packages at once, a single package can also only be updated to the latest patch version. To upgrade a single package to the latest patch version, you can use one of two ways. The first, using the -u=patch flag: go get -u=patch github.com/go-kit/log and the second, using @patch version query: go get -u github.com/go-kit/log@patch\nBoth of these commands upgrade the specified package to the latest patch version, which means that any changes to the minor or major versions of the package will be ignored.\n","date":"17 May 2023","permalink":"https://gosamples.dev/update-all-packages/","section":"Tutorials","summary":"","title":"🆕 How to update all Go packages to the latest version"},{"content":"In web development, a common task is to combine different URL elements into one, for example, if you are developing a REST API client and want to concatenate a given hostname with relative paths to endpoints. In Go since version 1.19 this is very easy, just use the url.JoinPath() function from the net/url package. Alternatively, you can also use the JoinPath() method of the URL struct from the same package.\nThese functions can help you avoid common errors that can arise when manually concatenating path elements, for example, double slashes or missing slashes in the final URL, which can cause unexpected behavior.\nExamples #The basic use of the url.JoinPath() function is straightforward. You simply pass the base URL as the first argument, and pass further elements of the URL you want to join to the base one as subsequent arguments. The signature of the function looks as follows:\nfunc JoinPath(base string, elem ...string) (result string, err error) The url.JoinPath() function automatically takes care of the correct formatting of the resulting URL, ensuring that it is well-formatted without redundant / or ../ characters.\nTake a look at the example below to see how it works:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { hostname := \u0026#34;https://gosamples.dev/\u0026#34; path1 := \u0026#34;//join-url-elements//\u0026#34; path2 := \u0026#34;/foo/\u0026#34; path3 := \u0026#34;//bar\u0026#34; result, err := url.JoinPath(hostname, path1, path2, path3) if err != nil { log.Fatal(err) } fmt.Println(result) } In the output you will get the resulting URL cleaned of redundant elements as a string:\nhttps://gosamples.dev/join-url-elements/foo/bar Alternatively, if you have a URL as a url.URL type and also want to get a url.URL structure as a result, you can use the JoinPath() method, passing as arguments only the new elements you want to join to the existing URL. The method works exactly the same as the url.JoinPath() function from the previous example:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { gosamplesURL, err := url.Parse(\u0026#34;https://gosamples.dev/\u0026#34;) if err != nil { log.Fatal(err) } path1 := \u0026#34;//join-url-elements//\u0026#34; path2 := \u0026#34;/foo/\u0026#34; path3 := \u0026#34;//bar\u0026#34; newGosamplesURL := gosamplesURL.JoinPath(path1, path2, path3) if err != nil { log.Fatal(err) } fmt.Println(newGosamplesURL) } In the output, you will get the resulting URL cleaned of unnecessary elements as a url.URL struct:\nhttps://gosamples.dev/join-url-elements/foo/bar And that\u0026rsquo;s it. Happy coding! 👨‍💻✨🎉\n","date":"11 May 2023","permalink":"https://gosamples.dev/join-url-elements/","section":"Tutorials","summary":"","title":"🔗 Join URL path elements in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/net/","section":"Tags","summary":"","title":"Net"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/path/","section":"Tags","summary":"","title":"Path"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/shorts/","section":"Tags","summary":"","title":"Shorts"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/url/","section":"Tags","summary":"","title":"Url"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/http/","section":"Tags","summary":"","title":"Http"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/httptest/","section":"Tags","summary":"","title":"Httptest"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/testing/","section":"Tags","summary":"","title":"Testing"},{"content":"Many programming languages, including Go, have frameworks for performing HTTP end-to-end (e2e) tests. However, not everyone knows that such tests can be performed using the httptest package built into the Go standard library. In this short article, we will show you how to do it - we will prepare end-to-end tests for a simple endpoint using only the httptest.Server from the httptest package.\nEnd-to-end (e2e) testing is a type of software testing that aims to verify the functionality and behavior of an application from start to finish, simulating real-world scenarios.\nIn the case of an HTTP server, simulating real-world scenarios involves creating a test environment that is equivalent to the production environment, including the database, network and any other external dependencies. Once created, the test environment is used in e2e testing to send real HTTP requests with various parameters, headers and content. The corresponding HTTP responses from the server are verified by the tests to make sure everything works as intended, just as it would on a production environment.\nHTTP handler for testing #Before we move on to testing, we need to create the web application that we will test. As the simplest example, we only need a single HTTP handler function such as HTTP Hello World:\nhello_world.go\n1 2 3 4 5 6 7 8 9 10 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/http\u0026#34; ) func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, \u0026#34;Hello World\u0026#34;) } The only thing this handler does is to write the string \u0026ldquo;Hello World\u0026rdquo; in response to the HTTP request.\nEnd-to-end test example #We will use httptest.Server to perform e2e tests. The httptest.Server is a structure built-in in Golang\u0026rsquo;s standard library (in the httptest package) that allows developers to create HTTP servers for testing purposes. This struct is useful when testing HTTP handlers, routers, and middlewares. It allows to test the operation of the application from start to finish locally, without setting up a separate testing environment on the remote host.\nIn the constructor, it accepts http.Handler as an input argument, so you can even use it to connect an entire application hidden behind a request router:\nfunc NewServer(handler http.Handler) *httptest.Server In our case, the handler will be our simple HelloWorld function converted using http.HandlerFunc().\nWe will perform end-to-end test in the standard hello_world_test.go file using the testing package. However, there is no problem to create a separate testing script working according to your own rules.\nTake a look at our sample end-to-end test below:\nhello_world_test.go\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package main import ( \u0026#34;io\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;net/http/httptest\u0026#34; \u0026#34;testing\u0026#34; ) func TestHelloWorld(t *testing.T) { testServer := httptest.NewServer(http.HandlerFunc(HelloWorld)) defer testServer.Close() testClient := testServer.Client() resp, err := testClient.Get(testServer.URL) if err != nil { t.Errorf(\u0026#34;Get error: %v\u0026#34;, err) } if resp.StatusCode != http.StatusOK { t.Errorf(\u0026#34;response code is not 200: %d\u0026#34;, resp.StatusCode) } data, err := io.ReadAll(resp.Body) if err != nil { t.Errorf(\u0026#34;io.ReadAll error: %v\u0026#34;, err) } if string(data) != \u0026#34;Hello World\\n\u0026#34; { t.Error(\u0026#34;response body does not equal to Hello World\u0026#34;) } } In lines 11 and 12 we initialize a new httptest.Server with our handler and instruct it to close at the end of the test with the word defer. The server has a custom client configured to make requests to the server, which we get and use from line 13. Using the client, we make a request to the server address (line 15), and then test the response, checking that it has the right status code (line 20) and the right body content (line 27). So as you can see, testing web applications this way is very easy. All you need to do is to initialize httptest.Server, and then use it and its client to make HTTP requests, which you can then verify using test functions. The httptest.Server significantly simplifies the testing of HTTP applications and it is worth knowing this method when working with such applications on a daily basis.\n","date":"9 May 2023","permalink":"https://gosamples.dev/e2e-httptest/","section":"Tutorials","summary":"","title":"🧪 Write end-to-end tests in Go using httptest.Server"},{"content":"In today\u0026rsquo;s world of cloud computing and distributed systems, networking plays a critical role. One of the most common tasks in networking is to obtain the local outbound IP address of a machine. This can be useful for various reasons, such as identifying your machine on a network, checking for network connectivity, or accessing external services that require your IP address.\nIn this blog post, we will explore how to get a local outbound IP address in Go application and explain the different methods available.\nLocal IP address vs Public IP address #Before we start, let\u0026rsquo;s recap what the difference between a local and public IP address is.\nLocal IP and Public IP are two types of IP addresses used in computer networking. The main difference between them is their scope of usage and reachability.\nA local IP address is used for communication within a local network, such as a home or office network. It is also known as a private IP address and is assigned to a device by a local router. Local IP addresses typically begin with 192.168.x.x, 172.16.x.x to 172.31.x.x, or 10.x.x.x.\nOn the other hand, a public IP address is used for communication over the Internet. It is assigned to a device by an Internet Service Provider (ISP) and is unique globally. Public IP addresses are necessary for devices that need to communicate outside of a local network, such as accessing websites or remote servers.\nIn summary, local IP addresses are used for internal communication within a network, while public IP addresses are used for external communication over the Internet.\nIn this blog post we are going to show you how to extract the local IP address of your machine.\nGet preferred outbound IP address using UDP #The first method of getting the local IP address from within the Go application is to use a UDP (User Datagram Protcol) connection. You need to prepare a UDP connection to any external address, and then from such a connection you can pull the preferred local outbound IP address. Look at the GetLocalIP() function in the following example:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net\u0026#34; ) func GetLocalIP() net.IP { conn, err := net.Dial(\u0026#34;udp\u0026#34;, \u0026#34;8.8.8.8:80\u0026#34;) if err != nil { log.Fatal(err) } defer conn.Close() localAddress := conn.LocalAddr().(*net.UDPAddr) return localAddress.IP } func main() { fmt.Println(GetLocalIP()) } We use the net.Dial() function from the net package to prepare a UDP connection to the Google DNS server (8.8.8.8). The destination address and port does not matter, it may not even exist, the only requirement is that the address be external. Because of how UDP works, the connection is not established anyway - no handshake is performed, no data is sent.\nThe purpose of this example is to get the local IP address that a UDP connection would use if it were sending data to the destination address. This can be done using the LocalAddr() method of the connection created. It returns the net.Addr interface, which can then be casted using type assertion to a specific net.UDPAddr so that the IP address can be extracted as a net.IP struct.\nGet local IP address by looping through all network interface addresses #Another way to get a local IP address is to iterate through all network interface addresses. They can be retrieved using the net.InterfaceAddrs() function. Take a look at the example:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net\u0026#34; ) func GetLocalIPs() ([]net.IP, error) { var ips []net.IP addresses, err := net.InterfaceAddrs() if err != nil { return nil, err } for _, addr := range addresses { if ipnet, ok := addr.(*net.IPNet); ok \u0026amp;\u0026amp; !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { ips = append(ips, ipnet.IP) } } } return ips, nil } func main() { ips, err := GetLocalIPs() if err != nil { log.Fatal(err) } fmt.Println(ips) } We cast all addresses to the net.IPNet struct, then filter out Loopback addresses and take only IPv4 IPs to the resulting list. This method extracts all local addresses, so if your machine has more than one local IP assigned, then the resulting slice will have more than one element.\n","date":"4 May 2023","permalink":"https://gosamples.dev/local-ip-address/","section":"Tutorials","summary":"","title":"🏠 Get local IP address in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/ip/","section":"Tags","summary":"","title":"Ip"},{"content":"To run an application in Go as an executable program you need an entry point - the place where the program execution begins. Such an entry point is the main() function in the package named main. When you compile your Go program, the main() function in the main package is automatically compiled into an executable file. This executable file can then be executed on any machine that has a compatible operating system and architecture.\nThe main package #In Go, every .go file starts with a package declaration:\n1 2 3 4 package main // the rest of the .go file // ... The package name is arbitrary, but a package named main has a special meaning. When you name your package like this, it is an indicator to the Go environment that it should be compiled into an executable program. In this package, the compiler will look for the main() function, which is the entry point of the application.\nThe main() function #The main() function is the entry point of any executable program. It is the function that the Go runtime calls to start the program. The main() function must have no arguments and no return values.\nHere is an example of a basic main() function in Go:\n1 2 3 4 5 6 7 package main import \u0026#34;fmt\u0026#34; func main() { fmt.Println(\u0026#34;Hello, world!\u0026#34;) } In this example, the main() function is the starting point of the program. It simply prints out \u0026quot;Hello, world!\u0026quot; to the console using the fmt.Println() function. As you already know, the main() function must be defined in a file with a package main. This tells the Go compiler that the file contains the entry point for an executable program.\nThe main() function can include any Go code that you want to execute when the program starts. It is the first function that is executed when you run the app. Typically, it sets up the initial state of the program, performs any necessary initialization, and then starts the program’s main loop.\nThe main.go file #The file main.go is the conventional name of the file in which the entry point to the program is located, that is, the main() function in the main package. In fact, this file can have any name you like, e.g. start.go, but it is good to follow the convention and always call such a file main.go. This makes it easier to find the starting point in the project.\nRun the main.go file #Once you have the main() function defined in the main package in the main.go file, you can go ahead and run your program. To run a main.go file, you can follow these steps:\nOpen your Terminal or command prompt. Navigate to the directory where your main.go file is located. Type the command go run main.go in the Terminal and press Enter. This command will compile and run your Go program. If there are no errors in your code, you should see the output in the Terminal. Alternatively, if you want to compile your Go program into an executable file, you can follow these steps:\nOpen your Terminal and navigate to the directory where your main.go file is located. Use the command go build in the Terminal. This will generate an executable with the same name as your source code directory. You can then run this file by typing ./myapp in the Terminal. FAQ #We cover more advanced topics in the form of answers to frequently asked questions.\nWhere to put the main.go file in the project? #The location of the main.go file can vary depending on the specific project and development environment you are using. In theory, the location inside the project can be whatever you want, the only thing to remember is that all files in the directory where main.go is located must be of the main package.\nIn practice, however, there are two common approaches to locating the main.go file.\nPutting the main.go file in the root directory of the project - if you are creating a small project or a single-file Go program. myapp/ ├── somecode.go ├── ... └── main.go For larger projects, it is common to organize code into packages and subdirectories. Commands (executable programs) are usually placed in a directory named cmd. In the cmd directory, you can create a subdirectory for each command you want to build, and each subdirectory contains a main.go file with the main package and main() function. myapp/ ├── cmd │ ├── app1 │ | └── main.go │ └── app2 │ └── main.go ├── pkg/ │ └── ... ├── internal/ │ └── ... └── ... Is the main.go file, the main package and the main() function required in a Go project? #No, a Go project does not need to have a file, package and function main. Then it is not intended to be built as an executable program, but rather as a package (library) that can be imported and used by other programs.\nThe main() function in the main package is required in a Go project that is intended to be built as an executable program. This function is the entry point of the program and it is where the execution of the program begins.\nIs it possible to import the main package? #No, you cannot import the main package in Go. The main is a special package that is used to create executable programs. It is not intended to be imported by other packages. Trying to do this you will get an error from the compiler: import \u0026quot;\u0026lt;package-name\u0026gt;\u0026quot; is a program, not an importable package.\nOther packages that you create can be imported by the main package, but the main itself cannot be imported by any other package.\nWhat is the difference between the main() and init() functions in Go? #The init() and main() are two distinct functions with different purposes.\nThe init() is a special function that is executed automatically when a Go program starts. Its purpose is to perform any initialization tasks that need to be done before the main() function runs. The init() can be defined in any package, and multiple such functions can be defined in the same package. They are then run all before the main() function.\nThe main() function is the entry point of a Go program. It is the function that is executed when the application starts. It can be defined only once in a program, and it must be defined in the main package.\nTo summarize, the init() function is used for initialization tasks, and it is executed automatically before the main() function. The main() is the entry point of a Go program, and it is executed after the init() function (if it exists).\nCan I have multiple main() functions in one project? #In Go, it is not possible to have multiple main() functions in the same main package. This is because the main() is a special function that serves as the entry point for the executable program.\nHowever, you can have multiple main packages in the same project, each with its own main() function. The only requirement is that each of these main packages be in a separate folder. This is how you organize the code in projects that have multiple executables. Each command (executable program) is placed in a separate subfolder in the cmd directory. Each such subfolder contains the main.go file with the main() function in the main package. See the answer to the question \u0026ldquo;Where to put the main.go file in the project?\u0026rdquo; for more details.\nCan the main package in Go consist of multiple files? #Yes, the main package in Go can consist of multiple files. The only disadvantage you need to keep in mind is that you need to specify all the files containing the main package when running through the go run command. Also, a multi-file main package, like a single-file package, can only contain one main() function.\nLet\u0026rsquo;s assume that you want to split the main package into two files: main.go and foo.go:\nmyapp/ ├── foo.go └── main.go An example code of the main.go file:\npackage main func main() { foo() } An example code of the foo.go file:\npackage main import \u0026#34;fmt\u0026#34; func foo() { fmt.Println(\u0026#34;foo\u0026#34;) } As you can see, both files belong to the main package.\nIf you run the above program with the go run main.go command, you will get an error: ./main.go:4:2: undefined: foo. This is because you have not specified all the main package files that are needed to run the application. If you run this program with the go run main.go foo.go command, then it will run without errors:\nfoo Providing a list of all the files of the main package to the go run can be troublesome especially if this package is split into many files. Therefore, some simplification has been made and the multi-file main package can also be run via the go run . command, which runs all the files in the current folder.\nIf you run the go build or go install commands you must also remember to specify all the files of the main package: go build main.go foo.go or use the default versions of these commands that build/install files from the current directory: go build and go install.\nDoes the main package have to contain the main() function? #Yes, in Go, the main package must contain a function named main(). When you run a program, the Go compiler looks for the main() function in the main package and executes it. If the main() function is not present or has a different signature, the compiler will not be able to execute the program, and you will get a compile-time error: runtime.main_main·f: function main is undeclared in the main package.\n","date":"20 March 2023","permalink":"https://gosamples.dev/main-function-package-file/","section":"Tutorials","summary":"","title":"🫶 The 'main()' function, 'main' package and 'main.go' file in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/id/","section":"Tags","summary":"","title":"Id"},{"content":"UUID (Universally Unique Identifier) is a 128-bit value used to uniquely identify information in computer systems. UUIDs are generated using algorithms that guarantee that each of them is unique.\nThey are commonly used in programming languages to uniquely identify objects or data. UUIDs can be represented in various formats, but the most commonly used is the hyphenated format, which looks like this:\n53aa35c8-e659-44b2-882f-f6056e443c99 In Go, there are many packages with which you can generate a UUID. Some of the more popular ones are github.com/google/uuid and github.com/gofrs/uuid. Both of these are based on RFC 4122 specification and support UUID generation in various versions. In this article, we provide examples of how to generate UUIDs with them in the default way, as well as using more advanced UUID version selection options.\nGenerate UUID using the github.com/google/uuid package #To generate a UUID using the github.com/google/uuid package, you must first download and install it using the go get Terminal command:\ngo get github.com/google/uuid Now, you can use this package in your code:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;github.com/google/uuid\u0026#34; ) func main() { uuid := uuid.NewString() fmt.Println(uuid) } The uuid.NewString() is the simplest function to generate UUID using the github.com/google/uuid package. It returns a random (Version 4) UUID as a string ready to use or print.\nUUIDs are standardized and come in many variants and versions. If you want to know them all, a good place to start is to read the Wikipedia article here. Different versions of UUIDs are based on different information:\nVersion 1 UUIDs are generated from a time and the MAC address. Version 2 UUIDs are generated from an identifier (usually user ID), time, and the MAC address. Version 3 and 5 UUIDs are generated based on hashing a namespace identifier and name. Version 4 UUIDs are based on a randomly generated number. After running the application, you will see a randomly generated UUID in the output:\n8cfb429e-0220-42a9-919c-54d6886d5128 Generate UUID using the github.com/gofrs/uuid package #To get and install the github.com/gofrs/uuid package, you need to execute the command below:\ngo get github.com/gofrs/uuid After that, you can generate UUID using this package in your app:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;github.com/gofrs/uuid\u0026#34; ) func main() { uuid, err := uuid.NewV4() if err != nil { log.Fatalf(\u0026#34;failed to generate UUID: %v\u0026#34;, err) } fmt.Println(uuid) } The example above shows how to generate version 4 UUID. All you need to do is use the uuid.NewV4() function.\nAs before, the output of the app is a randomly generated ID:\na40d6058-069e-4a7a-b873-41e3bff827be Generate a UUID of a specific version #If you are curious about how you can generate a UUID in a different version than the most popular Version 4, here is how you can do it using both packages.\nWith the github.com/google/uuid package #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;github.com/google/uuid\u0026#34; ) func main() { // version 1 uuid v1, err := uuid.NewUUID() if err != nil { log.Fatal(\u0026#34;cannot generate v1 uuid\u0026#34;) } fmt.Printf(\u0026#34;v1 uuid: %v\\n\u0026#34;, v1) // version 2 uuid v2, err := uuid.NewDCEGroup() if err != nil { log.Fatal(\u0026#34;cannot generate v2 uuid\u0026#34;) } fmt.Printf(\u0026#34;v2 uuid: %v\\n\u0026#34;, v2) // version 3 uuid v3 := uuid.NewMD5(uuid.NameSpaceURL, []byte(\u0026#34;https://example.com\u0026#34;)) fmt.Printf(\u0026#34;v3 uuid: %v\\n\u0026#34;, v3) // version 4 uuid v4, err := uuid.NewRandom() if err != nil { log.Fatal(\u0026#34;cannot generate v4 uuid\u0026#34;) } fmt.Printf(\u0026#34;v4 uuid: %v\\n\u0026#34;, v4) // version 5 uuid v5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte(\u0026#34;https://example.com\u0026#34;)) fmt.Printf(\u0026#34;v5 uuid: %v\\n\u0026#34;, v5) } With the github.com/gofrs/uuid package #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;github.com/gofrs/uuid\u0026#34; ) func main() { // version 1 uuid v1, err := uuid.NewV1() if err != nil { log.Fatal(\u0026#34;cannot generate v1 uuid\u0026#34;) } fmt.Printf(\u0026#34;v1 uuid: %v\\n\u0026#34;, v1) // version 3 uuid v3 := uuid.NewV3(uuid.NamespaceURL, \u0026#34;https://example.com\u0026#34;) fmt.Printf(\u0026#34;v3 uuid: %v\\n\u0026#34;, v3) // version 4 uuid v4, err := uuid.NewV4() if err != nil { log.Fatal(\u0026#34;cannot generate v4 uuid\u0026#34;) } fmt.Printf(\u0026#34;v4 uuid: %v\\n\u0026#34;, v4) // version 5 uuid v5 := uuid.NewV5(uuid.NamespaceURL, \u0026#34;https://example.com\u0026#34;) fmt.Printf(\u0026#34;v5 uuid: %v\\n\u0026#34;, v5) } Note that the github.com/gofrs/uuid package does not support UUID generation in version 2, but instead supports experimental versions 6 and 7 (not present in the example above).\nWhich UUID version to use? # If you simply need a unique random UUID without going into details, use Version 4. If you need a unique random UUID and want to know which one was generated from your computer, use Version 1. The IDs in Version 1 are generated based on time and MAC address and contain both a random and a constant element to identify the computer from which they were generated. Use Version 3 or 5 UUID generation if you need reproducible results, i.e. you want to always get the same ID for a given string. Because Version 5 uses the SHA-1 hashing algorithm, it is generally more secure and recommended than Version 3 which uses MD5. ","date":"2 March 2023","permalink":"https://gosamples.dev/generate-uuid/","section":"Tutorials","summary":"","title":"🆔 Generate UUID in Go"},{"content":"To convert time.Time to a string in Go, you can use the Time.String() method, which outputs the time in a default format, or Time.Format() method if you need a custom format.\nLook at the example below where we convert the current time in UTC timezone: t := time.Now().UTC() to a string. The s1 string is created by calling the t.String() method, and as you can see in the output, it is formatted using the default format: 2006-01-02 15:04:05.999999999 -0700 MST. On the other hand, the second string s2 is formatted by t.Format() method with the year-month-day format as an argument: 2006-01-02.\nIf you are unfamiliar with the Go time format layout, also called the reference time, check out our cheatsheet about date and time format in Go.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func main() { t := time.Now().UTC() s1 := t.String() fmt.Printf(\u0026#34;s1: %s\\n\u0026#34;, s1) s2 := t.Format(\u0026#34;2006-01-02\u0026#34;) fmt.Printf(\u0026#34;s2: %s\\n\u0026#34;, s2) } Output:\ns1: 2022-12-13 05:32:03.27335197 +0000 UTC s2: 2022-12-13 ","date":"1 March 2023","permalink":"https://gosamples.dev/time-to-string/","section":"Tutorials","summary":"","title":"📝 Convert date or time to string in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/introduction/","section":"Tags","summary":"","title":"Introduction"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/time/","section":"Tags","summary":"","title":"Time"},{"content":"The time.Ticker is a very popular structure in Go that provides clock ticks at fixed intervals. Internally, it contains a channel that delivers subsequent ticks. Using this channel, we can create several different variants of the loop depending on the needs, for example, whether the loop should start immediately, whether we need a ticker value, or whether we want to stop the ticker properly while the program is running. All these cases will be described in this article 😊.\nSimple loop over a time.Ticker #When you want to perform some task every fixed period of time, use the standard for loop over the C channel of time.Ticker. Such a loop allows you to schedule cron-like tasks or worker functions, where some code executes every specified time. Check out the example and the output. We receive a tick in the loop every second and print its time. After 5 seconds of the main thread sleeping, the ticker stops, and the app finishes.\nThis type of time.Ticker loop is suitable for endless goroutines. However, if in a production application you allow a goroutine to terminate before the end of the program, it is better to use an example that guarantees that the goroutine will terminate correctly.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { ticker := time.NewTicker(1 * time.Second) go func() { for t := range ticker.C { log.Printf(\u0026#34;Tick at: %v\\n\u0026#34;, t.UTC()) // do something } }() time.Sleep(5 * time.Second) ticker.Stop() } Output:\n2022/12/06 07:05:49 Tick at: 2022-12-06 06:05:49.450700257 +0000 UTC 2022/12/06 07:05:50 Tick at: 2022-12-06 06:05:50.450801838 +0000 UTC 2022/12/06 07:05:51 Tick at: 2022-12-06 06:05:51.450907566 +0000 UTC 2022/12/06 07:05:52 Tick at: 2022-12-06 06:05:52.451003677 +0000 UTC A loop without getting the tick value #In many cases, you do not need to print the tick value or use it in any other way. So you can ignore it by using the blank identifier in the loop: for _ := range ticker.C or skip the assignment in the loop altogether: for range ticker.C. Check out the example:\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { ticker := time.NewTicker(1 * time.Second) go func() { for range ticker.C { log.Println(\u0026#34;Hey!\u0026#34;) } }() time.Sleep(5 * time.Second) ticker.Stop() } Output:\n2022/12/06 19:11:13 Hey! 2022/12/06 19:11:14 Hey! 2022/12/06 19:11:15 Hey! 2022/12/06 19:11:16 Hey! Run time.Ticker loop with immediate start #Sometimes you may want the time.Ticker loop to return a tick immediately, without waiting for the first tick from the C channel. It can be useful in applications that do some work every certain amount of time, but the same work should also be done right after startup. For example, an application that fills a cache with data should do this right after the start and then at equal intervals, such as every hour. Although the time.Ticker does not support such an option by default, we can simulate this using the classic for loop form:\nfor \u0026lt;initialization\u0026gt;; \u0026lt;condition\u0026gt;; \u0026lt;post-condition\u0026gt; { \u0026lt;loopBody\u0026gt; } When we leave the \u0026lt;condition\u0026gt; empty, meaning that it will be true, we assure that this loop will execute at least once immediately. Subsequent executions should take place according to incoming ticks, so we need to set reading from the Ticker.C channel as \u0026lt;post-condition\u0026gt;. Run the example and look at its output. The first execution of the loop is immediate because there are no additional conditions in the \u0026lt;initialization\u0026gt; and \u0026lt;condition\u0026gt; sections, and subsequent executions happen every second according to the \u0026lt;post-condition\u0026gt;.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { ticker := time.NewTicker(1 * time.Second) go func() { for ; ; \u0026lt;-ticker.C { log.Println(\u0026#34;Hey!\u0026#34;) } }() time.Sleep(5 * time.Second) ticker.Stop() } Output:\n2022/12/06 19:50:37 Hey! 2022/12/06 19:50:38 Hey! 2022/12/06 19:50:39 Hey! 2022/12/06 19:50:40 Hey! 2022/12/06 19:50:41 Hey! Run time.Ticker loop with an immediate start and get the ticker value #When you want to create a time.Ticker loop with the immediate first tick and use its value, you must first initialize the variable in the for loop and then assign successive tick values obtained from the time.Ticker to it. Read the example to find out how to do it:\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { ticker := time.NewTicker(1 * time.Second) go func() { for t := time.Now(); ; t = \u0026lt;-ticker.C { log.Printf(\u0026#34;Tick at: %v\\n\u0026#34;, t.UTC()) } }() time.Sleep(5 * time.Second) ticker.Stop() } Output:\n2022/12/07 06:08:24 Tick at: 2022-12-07 05:08:24.189026328 +0000 UTC 2022/12/07 06:08:25 Tick at: 2022-12-07 05:08:25.189313138 +0000 UTC 2022/12/07 06:08:26 Tick at: 2022-12-07 05:08:26.189548386 +0000 UTC 2022/12/07 06:08:27 Tick at: 2022-12-07 05:08:27.189798708 +0000 UTC 2022/12/07 06:08:28 Tick at: 2022-12-07 05:08:28.190043492 +0000 UTC Properly finish the time.Ticker goroutine #When you run the time.Ticker loop in a goroutine, and at some point, you want to stop processing, you need to perform two steps:\nstop the Ticker ensure that the goroutine in which the Ticker was operating terminated correctly To stop the Ticker, you need to run the Stop() method. However, the Stop() does not close the C channel. It only prevents new ticks from being sent. Thus, it does not automatically exit the loop and the goroutine. To close the goroutine, you need an additional signal that, when read, will cause it to close. So to achieve all this, we will use a for loop with a select statement. The select blocks and waits until one of its cases can run. In our situation, it should wait either for the value of the new tick from the C channel or for the signal to terminate the goroutine.\nLook at the main() function in the example. After 5 seconds of goroutine processing, we stop the Ticker using the Stop() method and send a new signal to the done channel. As a result, the Ticker stops receiving new ticks in the C channel, and the select statement reads the value from the done, which causes the goroutine to return. In the first 5 seconds of the app, there are only messages in the ticker.C channel, so the select always chooses the case with a read from this channel.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { ticker := time.NewTicker(1 * time.Second) done := make(chan struct{}) go func() { for { select { case \u0026lt;-done: return case \u0026lt;-ticker.C: log.Println(\u0026#34;Hey!\u0026#34;) } } }() time.Sleep(5 * time.Second) ticker.Stop() done \u0026lt;- struct{}{} log.Println(\u0026#34;Done\u0026#34;) } Output:\n2022/12/07 06:09:59 Hey! 2022/12/07 06:10:00 Hey! 2022/12/07 06:10:01 Hey! 2022/12/07 06:10:02 Hey! 2022/12/07 06:10:03 Hey! 2022/12/07 06:10:03 Done ","date":"27 February 2023","permalink":"https://gosamples.dev/range-over-ticker/","section":"Tutorials","summary":"","title":"✨ 5 different ways to loop over a time.Ticker in Go"},{"content":"Getting started # Generics release #Generics in Go are available since the version 1.18, released on March 15, 2022.\nGeneric function #With Generics, you can create functions with types as parameters. Instead of writing separate functions for each type like:\nfunc LastInt(s []int) int { return s[len(s)-1] } func LastString(s []string) string { return s[len(s)-1] } // etc. you can write a function with a type parameter:\nfunc Last[T any](s []T) T { return s[len(s)-1] } Type parameters are declared in square brackets. They describe types that are allowed for a given function:\nGeneric function call #You can call a generic function like any other function:\nfunc main() { data := []int{1, 2, 3} fmt.Println(Last(data)) data2 := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} fmt.Println(Last(data2)) } You do not have to explicitly declare the type parameter as in the example below, because it is inferred based on the passed arguments. This feature is called type inference and applies only to functions.\nfunc main() { data := []int{1, 2, 3} fmt.Println(Last[int](data)) data2 := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} fmt.Println(Last[string](data2)) } However, explicitly declaring concrete type parameters is allowed, and sometimes necessary, when the compiler is unable to unambiguously detect the type of arguments passed.\nConstraints # Definition #A constraint is an interface that describes a type parameter. Only types that satisfy the specified interface can be used as a parameter of a generic function. The constraint always appears in square brackets after the the type parameter name.\nIn the following example:\nfunc Last[T any](s []T) T { return s[len(s)-1] } the constraint is any. Since Go 1.18, any is an alias for interface{}:\ntype any = interface{} The any is the broadest constraint, which assumes that the input variable to the generic function can be of any type.\nBuilt-in constraints #In addition to the any constraint in Go, there is also a built-in comparable constraint that describes any type whose values can be compared, i.e., we can use the == and != operators on them.\nfunc contains[T comparable](elems []T, v T) bool { for _, s := range elems { if v == s { return true } } return false } The constraints package #More constraints are defined in the x/exp/constraints package. It contains constraints that permit, for example, ordered types (types that support the operators \u0026lt;, \u0026lt;=, \u0026gt;=, \u0026gt;), floating-point types, integer types, and some others:\nfunc Last[T constraints.Complex](s []T) {} func Last[T constraints.Float](s []T) {} func Last[T constraints.Integer](s []T) {} func Last[T constraints.Ordered](s []T) {} func Last[T constraints.Signed](s []T) {} func Last[T constraints.Unsigned](s []T) {} Check the documentation of the x/exp/constraints package for more information.\nCustom constraints #Constraints are interfaces, so you can use a custom-defined interface as a constraint on a function type parameter:\ntype Doer interface { DoSomething() } func Last[T Doer](s []T) T { return s[len(s)-1] } However, using such an interface as a constraint is no different from using the interface directly.\nAs of Go 1.18, the interface definition has a new syntax. Now it is possible to define an interface with a type:\ntype Integer interface { int } Constraints containing only one type have little practical use. But, when combined with the union operator |, we can define type sets without which complex constraints cannot exist.\nType sets #Using the union | operator, we can define an interface with more than one type:\ntype Number interface { int | float64 } This type of interface is a type set that can contain types or other types sets:\ntype Number interface { constraints.Integer | constraints.Float } Type sets help define appropriate constraints. For example, all constraints in the x/exp/constraints package are type sets declared using the union operator:\ntype Integer interface { Signed | Unsigned } Inline type sets #Type set interface can also be defined inline in the function declaration:\nfunc Last[T interface{ int | int8 | int16 | int32 }](s []T) T { return s[len(s)-1] } Using the simplification that Go allows for, we can omit the interface{} keyword when declaring an inline type set:\nfunc Last[T int | int8 | int16 | int32](s []T) T { return s[len(s)-1] } Type approximation #In many of the constraint definitions, for example in the x/exp/constraints package, you can find the special operator ~ before a type. It means that the constraint allows this type, as well as a type whose underlying type is the same as the one defined in the constraint. Take a look at the example:\npackage main import ( \u0026#34;fmt\u0026#34; ) type MyInt int type Int interface { ~int | int8 | int16 | int32 } func Last[T Int](s []T) T { return s[len(s)-1] } func main() { data := []MyInt{1, 2, 3} fmt.Println(Last(data)) } Without the ~ before the int type in the Int constraint, you cannot use a slice of MyInt type in the Last() function because the MyInt type is not in the list of the Int constraint. By defining ~int in the constraint, we allow variables of any type whose underlying type is int.\nGeneric types # Defining a generic type #In Go, you can also create a generic type defined similarly to a generic function:\ntype KV[K comparable, V any] struct { Key K Value V } func (v *KV[K, V]) Set(key K, value V) { v.Key = key v.Value = value } func (v *KV[K, V]) Get(key K) *V { if v.Key == key { return \u0026amp;v.Value } return nil } Note that the method receiver is a generic KV[K, V] type.\nWhen defining a generic type, you cannot introduce additional type parameters in its methods - the struct type parameters are only allowed.\nExample of usage #When initializing a new generic struct, you must explicitly provide concrete types:\nfunc main() { var record KV[string, float64] record.Set(\u0026#34;abc\u0026#34;, 54.3) v := record.Get(\u0026#34;abc\u0026#34;) if v != nil { fmt.Println(*v) } } You can avoid it by creating a constructor function since types in functions can be inferred thanks to the type inference feature:\nfunc NewKV[K comparable, V any](key K, value V) *KV[K, V] { return \u0026amp;KV[K, V]{ Key: key, Value: value, } } func main() { record := NewKV(\u0026#34;abc\u0026#34;, 54.3) v := record.Get(\u0026#34;abc\u0026#34;) if v != nil { fmt.Println(*v) } NewKV(\u0026#34;abc\u0026#34;, 54.3) } ","date":"21 December 2022","permalink":"https://gosamples.dev/generics-cheatsheet/","section":"Tutorials","summary":"","title":"👑 Go Generics cheatsheet"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/cheatsheet/","section":"Tags","summary":"","title":"Cheatsheet"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/generics/","section":"Tags","summary":"","title":"Generics"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/generics-intro/","section":"Tags","summary":"","title":"Generics-Intro"},{"content":"To count the elements in a slice in Go that satisfy a certain condition, it is best to use Generics available since Go 1.18. With it, we can create a function that takes as arguments a slice of any type and a filter function that returns true or false for an element of that slice. In this way, we get a universal function that, for any slice, counts the occurrences of elements that meet any condition.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func count[T any](slice []T, f func(T) bool) int { count := 0 for _, s := range slice { if f(s) { count++ } } return count } func main() { s := []string{\u0026#34;ab\u0026#34;, \u0026#34;ac\u0026#34;, \u0026#34;de\u0026#34;, \u0026#34;at\u0026#34;, \u0026#34;gfb\u0026#34;, \u0026#34;fr\u0026#34;} fmt.Println( count( s, func(x string) bool { return strings.Contains(x, \u0026#34;a\u0026#34;) }), ) s2 := []int{1, 2, 3, 4, 5, 6} fmt.Println( count( s2, func(x int) bool { return x%3 == 0 }), ) } As you can see in the example, the count() function accepts a slice of a type parameter T, whose constraint is any - that is, it can be a slice of any type. The body of the function is simple. If the function f() returns true for a given slice element then the counter count increases by 1.\nIn the main(), you can see how versatile the count() function is. In the first case, we put a string slice as an argument and count the number of elements that contain the letter \u0026quot;a\u0026quot;. In the second case, we put an int slice and count the number of records divisible by 3. It is how the magic of Go Generics works. You do not need to write separate functions for each type - one is sufficient for all cases.\n","date":"15 December 2022","permalink":"https://gosamples.dev/generics-count/","section":"Tutorials","summary":"","title":"🫘 Count the occurrences of an element in a slice in Go"},{"content":"An HTTP client timeout is a time limit in which the server must process the request and return the response. If the set timeout is exceeded, the HTTP client should cancel the request and report an error. This mechanism is very important in applications that run in a production environment. It helps prevent the application from getting stuck waiting for a server response, which may take a long time or not happen at all.\nIn Go, the standard HTTP client does not set timeouts by default. It means that an app can wait for the server\u0026rsquo;s response forever. To prevent this, you should always remember to set a timeout in your HTTP client. And this is what we want to do here 🙂.\nThere are three scenarios of setting a timeout for HTTP requests that we are going to cover in this article:\nSetting the same timeout for all requests of a new http.Client. Setting a separate time limit for each new request. Modifying timeout for default HTTP client used by many external API client packages. Set timeout per HTTP client #If you want to set the same timeout for all requests of a new http.Client, initialize the client with the Timeout field set, where you specify the time limit in which the request must be processed.\nLook at the example:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package main import ( \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;time\u0026#34; ) func timeout(w http.ResponseWriter, req *http.Request) { time.Sleep(5 * time.Second) } func server() { go func() { http.HandleFunc(\u0026#34;/timeout\u0026#34;, timeout) log.Fatal(http.ListenAndServe(\u0026#34;:8090\u0026#34;, nil)) }() } func main() { server() httpClient := http.Client{Timeout: 2 * time.Second} if _, err := httpClient.Get(\u0026#34;http://localhost:8090/timeout\u0026#34;); err != nil { log.Fatal(err) } } In lines 9-18, we declare a new simple server whose only task is to pause work for 5 seconds by calling the time.Sleep function. In the first line of the main() function, we start this server. In the remaining lines, we create a new http.Client with the Timeout field set to 2 seconds and send a new request to the created server.\nSo by sending a request with a 2-second timeout to a server that pauses for 5 seconds, we will get a timeout error:\nOutput:\n2022/08/08 12:31:43 Get \u0026#34;http://localhost:8090/timeout\u0026#34;: context deadline exceeded (Client.Timeout exceeded while awaiting headers) exit status 1 If you run the app without the Timeout set, you will not get any error.\nSet timeout per request #If you want to set a timeout for an individual request, create a new request Context using the context.WithTimeout() function. Then, create a new request with this context as an argument using the http.NewRequestWithContext() constructor.\npackage main import ( \u0026#34;context\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;time\u0026#34; ) // func server() {...} the same as in the first example... func main() { server() httpClient := http.Client{} ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, http.MethodGet, \u0026#34;http://localhost:8090/timeout\u0026#34;, nil) if err != nil { log.Fatal(err) } if _, err := httpClient.Do(req); err != nil { log.Fatal(err) } } The context.Context is an object that is a common Go concept used by HTTP clients and servers to send/receive request-scoped values, cancellation, and deadline signals to deeper layers of services. In our case, the context is used to set the deadline for getting a response for a given new request.\nNote that in addition to the timeout value, the context.WithTimeout() function also takes a parent context as an argument, which in our example is a new empty context created with the context.Background() function. As a result, we receive the context and the cancellation function to release resources associated with it, which we call as a deferred function cancel().\nSince as in the previous example, we send a request with a 2-second timeout to the server that pauses for 5 seconds, we get a similar error message:\nOutput:\n2022/08/08 15:06:18 Get \u0026#34;http://localhost:8090/timeout\u0026#34;: context deadline exceeded exit status 1 Set timeout for default HTTP client #Sometimes you can use code that uses the default HTTP client: http.DefaultClient. Often there is no way to change this code so that it uses the custom-defined HTTP client, e.g. in external packages or in code where backward compatibility must be maintained. Fortunately, this does not mean that we cannot define a timeout for such a client. The example below shows how to do it.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;time\u0026#34; ) // func server() {...} the same as in the first example... func main() { server() http.DefaultClient.Timeout = 2 * time.Second if _, err := http.Get(\u0026#34;http://localhost:8090/timeout\u0026#34;); err != nil { log.Fatal(err) } } All you have to do is set the Timeout field in the default HTTP client, and then all functions of the http package using the default client will respect this timeout.\nIn this example, you get the same error message as if you set the timeout per HTTP client:\nOutput:\n2022/08/09 09:48:58 Get \u0026#34;http://localhost:8090/timeout\u0026#34;: context deadline exceeded (Client.Timeout exceeded while awaiting headers) exit status 1 ","date":"30 August 2022","permalink":"https://gosamples.dev/http-client-timeout/","section":"Tutorials","summary":"","title":"⏱️ Set HTTP client timeout in Go"},{"content":"To handle an HTTP timeout error in Go, use the os.IsTimeout() function from the built-in os package. It returns true if the request time limit has been exceeded or false otherwise.\nExample #In the example, we create an HTTP client with a timeout of 1 nanosecond. With such a short timeout, we can be sure that we will receive a timeout error when we send a request to the https://example.com server.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package main import ( \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;os\u0026#34; \u0026#34;time\u0026#34; ) func main() { httpClient := http.Client{Timeout: 1 * time.Nanosecond} req, err := http.NewRequest(http.MethodGet, \u0026#34;https://example.com\u0026#34;, nil) if err != nil { log.Fatal(err) } _, err = httpClient.Do(req) if os.IsTimeout(err) { log.Printf(\u0026#34;timeout error: %v\\n\u0026#34;, err) } } Output:\n2022/08/28 18:35:48 timeout error: Get \u0026#34;https://example.com\u0026#34;: context deadline exceeded (Client.Timeout exceeded while awaiting headers) Read this article to learn more about the context deadline exceeded, which is also a timeout error.\nTo make sure that os.IsTimeout() works correctly, change the timeout value in line 11 to 1 * time.Minute. If there is currently no problem with https://example.com, the request will be processed within the time limit of 1 minute and you will not see any error on the output.\n","date":"29 August 2022","permalink":"https://gosamples.dev/handle-http-timeout-error/","section":"Tutorials","summary":"","title":"⏰ Handle HTTP timeout error in Go"},{"content":"The recover() is a built-in function in Go that stops the program abort sequence invoked by the call of the panic() function. It restores the normal execution of the application and allows for handling the error passed to the panic(). In other words, recover() \u0026ldquo;catches\u0026rdquo; panic-type errors and allows you to handle them instead of terminating the application.\nPanic and Defer #The recover() works closely with the panic() function and the defer statement.\nThe panic() function is used in Go to report an unrecoverable state in the application that prevents it from running any longer. In general, there are two types of sources of such a state in an application:\nLack of access to resources necessary for the application to run. For example, a database connection error in an application that updates data in the database causes the application to be unable to continue running. In this case, you should either wait for access or explicitly terminate the application with an unrecoverable error using the panic() function. Programming bugs causing the runtime errors, such as indexing a slice out of bounds. They automatically trigger the panic() and terminate the app. A toy example showing how the panic() function works for the case when the application lacks access to resources:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; ) func connectToDB() error { return errors.New(\u0026#34;error while connecting to db\u0026#34;) } func main() { err := connectToDB() if err != nil { panic(err) } fmt.Println(\u0026#34;connected to db\u0026#34;) } Output:\npanic: error while connecting to db goroutine 1 [running]: main.main() main.go:15 +0x49 exit status 2 In the example, the connectToDB() function always returns an error that we use as an argument to the panic(). As a result, the last line of the main(), printing the \u0026quot;connected to db\u0026quot; string is never executed because the program starts the panicking sequence earlier, which results in logging the error to standard output and terminating the application.\nTo define what the panicking sequence is and how it works, we must first learn more about the defer statement.\nThe defer statement ensures that a function is executed after the surrounding function returns (the one in which defer was called). It does not matter whether the surrounding function ended without error or was interrupted by a panic. The defer guarantees that the function following this keyword will be executed.\nLook at the example:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package main import \u0026#34;fmt\u0026#34; func foo() { defer fmt.Println(\u0026#34;Bye foo\u0026#34;) fmt.Println(\u0026#34;Hello foo\u0026#34;) bar() fmt.Println(\u0026#34;After bar\u0026#34;) } func bar() { defer fmt.Println(\u0026#34;Bye bar\u0026#34;) fmt.Println(\u0026#34;Hello bar\u0026#34;) baz() fmt.Println(\u0026#34;After baz\u0026#34;) } func baz() { defer fmt.Println(\u0026#34;Bye baz\u0026#34;) fmt.Println(\u0026#34;Hello baz\u0026#34;) panic(\u0026#34;panic in baz\u0026#34;) } func main() { foo() fmt.Println(\u0026#34;After foo\u0026#34;) } As you can see, we call a sequence of three functions. The main() function calls foo(), which then calls bar(), and the bar() calls baz(). In each of them, we print out the string \u0026quot;Hello \u0026lt;function-name\u0026gt;\u0026quot; and in the first line declare the deferred function, which should print the string \u0026quot;Bye \u0026lt;function-name\u0026gt;\u0026quot;. After each of the three functions call, we print the string \u0026quot;After \u0026lt;function-name\u0026gt;\u0026quot;. Moreover, the baz() invokes a panic with the string \u0026quot;panic in baz\u0026quot;.\nThe program prints the following result to the output:\nHello foo Hello bar Hello baz Bye baz Bye bar Bye foo panic: panic in baz goroutine 1 [running]: main.baz() main.go:20 +0xb8 main.bar() main.go:14 +0xaa main.foo() main.go:8 +0xaa main.main() main.go:24 +0x17 exit status 2 In the beginning, everything works as expected - the foo(), bar(), and baz() functions are executed one by one and print out the \u0026quot;Hello \u0026lt;function-name\u0026gt;\u0026quot; messages. Inside the baz() function, there is a panic, but it is not immediately visible in the output. Instead, the baz(), bar() and foo() calls the deferred functions in sequence omitting the \u0026quot;After \u0026lt;function-name\u0026gt;\u0026quot; string printing.\nThat is how the panic() works - it starts the panicking sequence by immediately stopping the execution of the current function and starting to unwind the current goroutine function stack, running any deferred functions along the way. If this unwinding reaches the top of the stack, the panic is logged, and the program dies.\nThe diagram below shows how the panic() function and defer statement work in our example:\nSo, as a result of the panicking sequence, we can see the calls to defer statement functions that print the \u0026quot;Bye \u0026lt;function-name\u0026gt;\u0026quot; messages. During the panicking, the program do not call any other function than in the defer statement - it did not print out the \u0026quot;After \u0026lt;function-name\u0026gt;\u0026quot; strings. The panic itself is logged at the end when it reaches the top of the function stack. Because of that, you can see this log and stack trace as the last message in the output.\nOf course, as we mentioned at the beginning, the defer statement works regardless of whether panic occurs in the program or not. To check this, remove panic() from the app and trace the output. Naturally, this also works the other way around, meaning you also do not have to use defer when calling panic().\nRecover from a Panic #Sometimes you may want the panicking to abort, the application to return to normal execution, and the whole sequence of unwinding the goroutine function stack and terminating the application to stop. This is what the built-in recover() function is for.\nfunc recover() any\nThe recover() restores the normal execution of the program by stopping the panicking sequence. It returns the error value passed to the call of the panic(), or nil if the goroutine is not panicking.\nThe panic() can take any value as an argument, so the recover() also returns the value of type any. Since Go 1.18, any is an alias for interface{}.\nThe recover() is useful in any case, where a single panic should not terminate the entire program. For example, a critical error in one of the web server client connections should not crash the server app.\nIt is also used for handling errors in the recursive function stack. If an error occurs at some level of a call to such a function, it usually needs to be handled at the top. To do this, report the panic to unwind the stack to the top-level function call and then recover() from the panic to handle the error.\nWhen you store your application logs, the recover() can also be used to catch a panic and save the panic message to the storage.\nSince you already know what the recover() is and how it works, it\u0026rsquo;s time to show an example how to use it.\nThe following program is the same as the previous one except that this time we recover from the panic in the baz() function:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package main import ( \u0026#34;fmt\u0026#34; ) func foo() { defer fmt.Println(\u0026#34;Bye foo\u0026#34;) fmt.Println(\u0026#34;Hello foo\u0026#34;) bar() fmt.Println(\u0026#34;After bar\u0026#34;) } func bar() { defer fmt.Println(\u0026#34;Bye bar\u0026#34;) fmt.Println(\u0026#34;Hello bar\u0026#34;) baz() fmt.Println(\u0026#34;After baz\u0026#34;) } func baz() { defer recoverPanic() defer fmt.Println(\u0026#34;Bye baz\u0026#34;) fmt.Println(\u0026#34;Hello baz\u0026#34;) panic(\u0026#34;panic in baz\u0026#34;) } func recoverPanic() { if err := recover(); err != nil { fmt.Printf(\u0026#34;RECOVERED: %v\\n\u0026#34;, err) } } func main() { foo() fmt.Println(\u0026#34;After foo\u0026#34;) } Output:\nHello foo Hello bar Hello baz Bye baz RECOVERED: panic in baz After baz Bye bar After bar Bye foo After foo In the first line of the baz() there is a deferred panic recovery function recoverPanic() which checks whether the recover() returns a non-nil result. If so, then the panic argument is printed to the standard output with the prefix RECOVERED:.\nIn the output you can see that the application has indeed recovered the panic, as it returns to normal execution and prints the strings \u0026quot;After baz\u0026quot;, \u0026quot;After bar\u0026quot;, and \u0026quot;After foo\u0026quot;.\nOur sample application now looks like this in the diagram:\nYou may wonder why we called the recover() in a deferred function in baz(). Well, this is the first rule when using the recover() function:\nThe recover() only works in a deferred function.\nThis is because during the returning to the caller in panicking sequence, the only code that runs is deferred functions, so the recover() will not run elsewhere.\nThe second rule is:\nThe recover() only works in the same goroutine where panic() was thrown.\nLook at the example:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func barRecover() { fmt.Printf(\u0026#34;RECOVER: %v\\n\u0026#34;, recover()) } func bar() { defer fmt.Println(\u0026#34;deferred from bar\u0026#34;) panic(\u0026#34;panic in bar\u0026#34;) } func main() { defer barRecover() go func() { bar() }() time.Sleep(5 * time.Second) } Output:\ndeferred from bar panic: panic in bar goroutine 6 [running]: main.bar() recover/main.go:14 +0x73 main.main.func1() recover/main.go:20 +0x17 created by main.main recover/main.go:19 +0x45 exit status 2 In the main(), we declared a call to the deferred function barRecover(), which recovers from a panic. Then, we called the bar() function that panics in a new separate goroutine. As you can see in the output, the panic is not recovered since it was invoked by a new goroutine, and the recover() was in the main goroutine. In the diagram, it looks like this:\nWhen you replace the bar() call in a new goroutine:\n19 20 21 go func() { bar() }() with a regular call:\n19 bar() then the panic will be recovered and the output you will see will look like this:\ndeferred from bar RECOVER: panic in bar As a rule of thumb, remember this scheme and that you can only call recover() in the same goroutine as panic(). This will save you a lot of debugging time.\nConclusion #The recover() function is a great mechanism in Go to avoid killing the application when unrecoverable errors occur and handle them so that the application can continue to run. In summary, you should remember the 3 most important things about this function:\nThe recover() function is used to abort the panicking sequence and handle panics in the application. It only works in a deferred function. It only works in the same goroutine where panic() was thrown. ","date":"24 August 2022","permalink":"https://gosamples.dev/recover/","section":"Tutorials","summary":"","title":"❤️‍🩹 Recover function in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/builtin/","section":"Tags","summary":"","title":"Builtin"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/syntax/","section":"Tags","summary":"","title":"Syntax"},{"content":"To compare two strings in Go, you can use the comparison operators ==, !=, \u0026gt;=, \u0026lt;=, \u0026lt;, \u0026gt;. Alternatively, you can use the strings.Compare() function from the strings package.\nWhen comparing strings, we mean lexicographic (alphabetical) order.\nComparison operators #Strings in Go support comparison operators ==, !=, \u0026gt;=, \u0026lt;=, \u0026lt;, \u0026gt; to compare strings in lexicographic (alphabetical) order. The result of the comparison is a bool value (true or false) indicating if the condition is met.\nExample:\npackage main import \u0026#34;fmt\u0026#34; func main() { str1 := \u0026#34;gosamples\u0026#34; str2 := \u0026#34;dev\u0026#34; str3 := \u0026#34;gosamples\u0026#34; fmt.Printf(\u0026#34;%s == %s: %t\\n\u0026#34;, str1, str2, str1 == str2) fmt.Printf(\u0026#34;%s == %s: %t\\n\u0026#34;, str1, str3, str1 == str3) fmt.Printf(\u0026#34;%s != %s: %t\\n\u0026#34;, str1, str2, str1 != str2) fmt.Printf(\u0026#34;%s != %s: %t\\n\\n\u0026#34;, str1, str3, str1 != str3) fmt.Printf(\u0026#34;%s \u0026gt;= %s: %t\\n\u0026#34;, str1, str2, str1 \u0026gt;= str2) fmt.Printf(\u0026#34;%s \u0026gt;= %s: %t\\n\u0026#34;, str1, str3, str1 \u0026gt;= str3) fmt.Printf(\u0026#34;%s \u0026gt; %s: %t\\n\u0026#34;, str1, str2, str1 \u0026gt; str2) fmt.Printf(\u0026#34;%s \u0026gt; %s: %t\\n\\n\u0026#34;, str1, str3, str1 \u0026gt; str3) fmt.Printf(\u0026#34;%s \u0026lt;= %s: %t\\n\u0026#34;, str1, str2, str1 \u0026lt;= str2) fmt.Printf(\u0026#34;%s \u0026lt;= %s: %t\\n\u0026#34;, str1, str3, str1 \u0026lt;= str3) fmt.Printf(\u0026#34;%s \u0026lt; %s: %t\\n\u0026#34;, str1, str2, str1 \u0026lt; str2) fmt.Printf(\u0026#34;%s \u0026lt; %s: %t\\n\u0026#34;, str1, str3, str1 \u0026lt; str3) } Output:\ngosamples == dev: false gosamples == gosamples: true gosamples != dev: true gosamples != gosamples: false gosamples \u0026gt;= dev: true gosamples \u0026gt;= gosamples: true gosamples \u0026gt; dev: true gosamples \u0026gt; gosamples: false gosamples \u0026lt;= dev: false gosamples \u0026lt;= gosamples: true gosamples \u0026lt; dev: false gosamples \u0026lt; gosamples: false The strings.Compare() function #The strings.Compare() function compares two strings in lexicographic order returning an int value as a result:\nfunc Compare(a, b string) int\nThe result is:\n0 if a == b 1 if a \u0026gt; b -1 if a \u0026lt; b Example:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str1 := \u0026#34;gosamples\u0026#34; str2 := \u0026#34;dev\u0026#34; str3 := \u0026#34;gosamples\u0026#34; fmt.Printf(\u0026#34;strings.Compare(%s, %s): %d\\n\u0026#34;, str1, str2, strings.Compare(str1, str2)) fmt.Printf(\u0026#34;strings.Compare(%s, %s): %d\\n\u0026#34;, str1, str3, strings.Compare(str1, str3)) fmt.Printf(\u0026#34;strings.Compare(%s, %s): %d\\n\u0026#34;, str2, str1, strings.Compare(str2, str1)) } Output:\nstrings.Compare(gosamples, dev): 1 strings.Compare(gosamples, gosamples): 0 strings.Compare(dev, gosamples): -1 Case-insensitive string comparison #If you want to compare whether two strings are equal without paying attention to the case, you can perform a case-insensitive string comparison. Check out how to do it in our other tutorial.\n","date":"2 August 2022","permalink":"https://gosamples.dev/strings-compare/","section":"Tutorials","summary":"","title":"🐾 How to compare strings in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/strings/","section":"Tags","summary":"","title":"Strings"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/os/","section":"Tags","summary":"","title":"Os"},{"content":"To exit an application in Go, use the os.Exit() function from the os package. It causes the program to terminate immediately. The function takes a status code as an argument where the code zero indicates success and the non-zero an error.\nfunc Exit(code int)\nThe os.Exit() function terminates an app immediately, which means that if there are any deferred functions, they are not run.\nStatus codes #Typically, the status code 0 indicates an exit with no error, and 1 an exit with a general error. You can set the status code whatever you want, but keep in mind that some of them have special meanings, which you can check here.\nExample #Exit with status code 0 #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; ) func main() { fmt.Println(\u0026#34;Hello gosamples.dev\u0026#34;) os.Exit(0) fmt.Println(\u0026#34;Bye gosamples.dev\u0026#34;) } Output:\nHello gosamples.dev As you can see in the output, the app closes without any error immediately after calling the os.Exit(). The last line of the main() function is never executed.\nExit with status code 1 #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; ) func main() { fmt.Println(\u0026#34;Hello gosamples.dev\u0026#34;) os.Exit(1) fmt.Println(\u0026#34;Bye gosamples.dev\u0026#34;) } Output:\nHello gosamples.dev exit status 1 When shutting down an application with a status code other than 0, we see an additional message exit status \u0026lt;code\u0026gt; in the output, indicating that the application is terminated with an error.\nWhen to use os.Exit() and when to use panic()? # The os.Exit() function terminates the program immediately with no possibility of recovery and running deferred functions. The app returns an error code that other programs can read to check what happened. The panic() function is used to report unrecoverable errors in the program, for example, run-time errors such as indexing a slice out of bounds. It immediately stops the execution of the current function and starts to unwind the goroutine stack, running any deferred functions along the way. If that unwinding reaches the top of the goroutine\u0026rsquo;s stack, the program dies. Typically, when your application reaches an unrecoverable state and cannot continue due to a specific error, you should use the panic() function. With the panic(), the application closes gracefully, all deferred functions are executed, and the application prints an accurate error message to the output. The os.Exit() function, which closes the application immediately, can be used when you need from your application an error code that can be read by other scripts. It can also be used when your application has already done everything it should have done, and now it just needs to exit, such as after writing the results to the standard output or when the user runs a command to close the application.\n","date":"1 August 2022","permalink":"https://gosamples.dev/exit/","section":"Tutorials","summary":"","title":"🛑 Exit an app in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/categories/basics/","section":"Categories","summary":"","title":"Basics"},{"content":"","date":null,"permalink":"https://gosamples.dev/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/cli/","section":"Tags","summary":"","title":"Cli"},{"content":" Quick Answer: Run go version in your terminal to see your installed Go version. The current stable version is Go 1.25.5 (released December 2, 2025). To check the version of Go installed on your system, run go version in your terminal/shell/command line. To find out what version of Go a binary was built with, use go version \u0026quot;app-name\u0026quot; where \u0026quot;app-name\u0026quot; is the name of your built application. To figure out at runtime what version of Go an app was built with, use the runtime.Version() function. Check the Go version installed on your system #To find out what version of Go is installed on your system, open your terminal/command line/shell, and run the command:\ngo version The version is a command of the go tool which prints out version information for Go executables. If no additional arguments are given, it prints out the Go version installed on your computer.\nExample of the go version output:\ngo version go1.25.5 darwin/amd64 If you want to learn more about the go version, check the documentation using the command:\ngo help version Check what version of Go a binary was built with #To find out what version of Go a given application was built with, just use the go version command, passing the path to the binary as an argument:\ngo version \u0026lt;path/to/the/binary\u0026gt; Example #Create a simple app, for example the \u0026ldquo;Hello World\u0026rdquo; application, and save it as a main.go file:\npackage main import \u0026#34;fmt\u0026#34; func main() { fmt.Println(\u0026#34;Hello World!\u0026#34;) } Then build the application using the command:\ngo build -o hello-world Now you can check what version of Go the hello-world app was built with:\ngo version hello-world In the output, you should see the application name and version:\nhello-world: go1.25.5 Check build information and module dependencies #Starting with Go 1.13, you can use the go version -m command to inspect detailed build information including module dependencies embedded in a binary:\ngo version -m \u0026lt;path/to/the/binary\u0026gt; This command displays not only the Go version used to build the binary, but also:\nModule path and version Dependency modules and their versions Build settings Example #Using the same hello-world binary from the previous example:\ngo version -m hello-world Example output:\nhello-world: go1.25.5 path example.com/hello-world mod example.com/hello-world (devel) build -buildmode=exe build -compiler=gc build CGO_ENABLED=1 This is particularly useful for understanding the exact build configuration and dependencies of a production binary.\nCheck at runtime what version of Go the app was built with #If you want to check directly in the application what version of Go it was built with, you can use the runtime.Version() function. It returns the Go version information, the same as when using the go version \u0026lt;path/to/the/binary\u0026gt; command.\nExample #Create a new app that prints Go version information and save it as a main.go file:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;runtime\u0026#34; ) func main() { fmt.Println(\u0026#34;Hello World!\u0026#34;) fmt.Printf(\u0026#34;The application was built with the Go version: %s\\n\u0026#34;, runtime.Version()) } Build the application using the command:\ngo build -o hello-world-with-version Run the application:\n./hello-world-with-version In the output, you should see the Go version string:\nHello World! The application was built with the Go version: go1.25.5 Check Go version using go env #Another way to check your Go version is by using the go env command, which provides comprehensive information about your Go environment.\nTo get just the Go version:\ngo env GOVERSION Example output:\ngo1.25.5 To see all Go environment variables (including GOVERSION, GOROOT, GOPATH, and more):\ngo env This will display a complete list of environment variables that Go uses, which can be helpful for debugging and understanding your Go installation configuration.\nCurrent Go (Golang) version # The current major Go version is go1.25 (released on August 12, 2025). Read the Go 1.25 Release Notes for more information. The latest minor Go version is go1.25.5 (released on December 2, 2025). Read the Release History for more information about Go 1.25.5. Go support policy #Go follows a support policy where each major release is supported until there are two newer major releases. This means:\nCurrently supported versions: Go 1.24 and Go 1.25 Support includes: Security updates and critical bug fixes Older versions: Go 1.23 and earlier are no longer supported For example, when Go 1.26 is released, Go 1.24 will become the oldest supported version, and Go 1.23 will no longer receive updates.\nIt\u0026rsquo;s recommended to stay on one of the two most recent major Go versions to ensure you receive security patches and critical fixes. You can read more about the Go Release Policy on the official documentation.\nHow to upgrade to a newer version of Go? #To update your Go version, go to the official Download and install website. There you will find up-to-date information on how to update an existing version of Go on Linux, macOS, and Windows.\nTroubleshooting common issues #\u0026ldquo;go: command not found\u0026rdquo; #If you get this error, Go is either not installed or not in your system\u0026rsquo;s PATH. To fix this:\nVerify Go is installed by checking if the Go directory exists (typically /usr/local/go on Linux/macOS or C:\\Go on Windows) Add Go to your PATH by adding the following to your shell profile (.bashrc, .zshrc, etc.): export PATH=$PATH:/usr/local/go/bin Reload your shell or run source ~/.bashrc (or equivalent for your shell) Verify with go version Different versions in different terminals #If you see different Go versions in different terminal windows, you may have multiple Go installations.\nDiagnosing the issue:\nFirst, identify which Go binary is being used and where it\u0026rsquo;s installed:\nwhich go # Shows which Go binary is being used go env GOROOT # Shows where Go is installed go env GOPATH # Your Go workspace go env GOBIN # Where go install places binaries Fixing the issue:\nRemove old installations and ensure only one Go version is in your PATH, or use version managers like gvm or goenv to manage multiple versions cleanly.\nRelated commands and resources #Here are some related Go commands and resources that might be helpful:\nUseful Go commands # go version - Check Go version go env - Display Go environment variables go help - Display help documentation go doc - Show documentation for packages go list -m all - List all modules in your project External resources # Official Go Downloads - Download the latest Go version Go Release Notes - Complete release history and notes Go Installation Guide - Official installation instructions Go Getting Started - Official tutorial for beginners Go (Golang) version history #Major Go releases are labeled as, for example, 1.16, 1.17, 1.18 (in the list below, they are written in a larger font). In addition, there are support releases introducing minor fixes labeled as, for example, 1.17.1, 1.17.2, and so on. If you want to learn more about the release policy of Go, read the official documentation.\nGo was first publicly announced on November 10, 2009.\nThe first major version of Go - go1 was released on March 28, 2012.\ngo1.25.5 - released on December 2, 2025 go1.25.4 - released on November 5, 2025 go1.25.3 - released on October 13, 2025 go1.25.2 - released on October 7, 2025 go1.25.1 - released on September 3, 2025 go1.25 - released on August 12, 2025 go1.24.11 - released on December 2, 2025 go1.24.10 - released on November 5, 2025 go1.24.9 - released on October 13, 2025 go1.24.8 - released on October 7, 2025 go1.24.7 - released on September 3, 2025 go1.24.6 - released on August 6, 2025 go1.24.5 - released on July 8, 2025 go1.24.4 - released on June 5, 2025 go1.24.3 - released on May 6, 2025 go1.24.2 - released on April 1, 2025 go1.24.1 - released on March 4, 2025 go1.24 - released on February 11, 2025 go1.23.12 - released on August 6, 2025 go1.23.11 - released on July 8, 2025 go1.23.10 - released on June 5, 2025 go1.23.9 - released on May 6, 2025 go1.23.8 - released on April 1, 2025 go1.23.7 - released on March 4, 2025 go1.23.6 - released on February 4, 2025 go1.23.5 - released on January 16, 2025 go1.23.4 - released on December 3, 2024 go1.23.3 - released on November 6, 2024 go1.23.2 - released on October 1, 2024 go1.23.1 - released on September 5, 2024 go1.23 - released on August 13, 2024 go1.22.12 - released on February 4, 2025 go1.22.11 - released on January 16, 2025 go1.22.10 - released on December 3, 2024 go1.22.9 - released on November 6, 2024 go1.22.8 - released on October 1, 2024 go1.22.7 - released on September 5, 2024 go1.22.6 - released on August 6, 2024 go1.22.5 - released on July 2, 2024 go1.22.4 - released on June 4, 2024 go1.22.3 - released on May 7, 2024 go1.22.2 - released on April 3, 2024 go1.22.1 - released on March 5, 2024 go1.22 - released on February 6, 2024 go1.21.13 - released on August 6, 2024 go1.21.12 - released on July 2, 2024 go1.21.11 - released on June 4, 2024 go1.21.10 - released on May 7, 2024 go1.21.9 - released on April 3, 2024 go1.21.8 - released on March 5, 2024 go1.21.7 - released on February 6, 2024 go1.21.6 - released on January 9, 2024 go1.21.5 - released on December 5, 2023 go1.21.4 - released on November 7, 2023 go1.21.3 - released on October 10, 2023 go1.21.2 - released on October 5, 2023 go1.21.1 - released on September 6, 2023 go1.21 - released on August 8, 2023 go1.20.6 - released on July 11, 2023 go1.20.5 - released on June 6, 2023 go1.20.4 - released on May 2, 2023 go1.20.3 - released on April 4, 2023 go1.20.2 - released on March 7, 2023 go1.20.1 - released on February 14, 2023 go1.20 - released on February 1, 2023 go1.19.11 - released on July 11, 2023 go1.19.10 - released on June 6, 2023 go1.19.9 - released on May 2, 2023 go1.19.8 - released on April 4, 2023 go1.19.7 - released on March 7, 2023 go1.19.6 - released on February 14, 2023 go1.19.5 - released on January 10, 2023 go1.19.4 - released on December 6, 2022 go1.19.3 - released on November 1, 2022 go1.19.2 - released on October 4, 2022 go1.19.1 - released on September 6, 2022 go1.19 - released on August 2, 2022 go1.18.10 - released on January 10, 2023 go1.18.9 - released on December 6, 2022 go1.18.8 - released on November 1, 2022 go1.18.7 - released on October 4, 2022 go1.18.6 - released on September 6, 2022 go1.18.5 - released on August 1, 2022 go1.18.4 - released on July 12, 2022 go1.18.3 - released on June 1, 2022 go1.18.2 - released on May 10, 2022 go1.18.1 - released on April 12, 2022 go1.18 - released on March 15, 2022 go1.17.13 - released on August 1, 2022 go1.17.12 - released on July 12, 2022 go1.17.11 - released on June 1, 2022 go1.17.10 - released on May 10, 2022 go1.17.9 - released on April 12, 2022 go1.17.8 - released on March 3, 2022 go1.17.7 - released on February 10, 2022 go1.17.6 - released on January 6, 2022 go1.17.5 - released on December 9, 2021 go1.17.4 - released on December 2, 2021 go1.17.3 - released on November 4, 2021 go1.17.2 - released on October 7, 2021 go1.17.1 - released on September 9, 2021 go1.17 - released on August 16, 2021 go1.16.15 - released on March 3, 2022 go1.16.14 - released on February 10, 2022 go1.16.13 - released on January 6, 2022 go1.16.12 - released on December 9, 2021 go1.16.11 - released on December 2, 2021 go1.16.10 - released on November 4, 2021 go1.16.9 - released on October 7, 2021 go1.16.8 - released on September 9, 2021 go1.16.7 - released on August 5, 2021 go1.16.6 - released on July 12, 2021 go1.16.5 - released on June 3, 2021 go1.16.4 - released on May 6, 2021 go1.16.3 - released on April 1, 2021 go1.16.2 - released on March 11, 2021 go1.16.1 - released on March 10, 2021 go1.16 - released on February 16, 2021 go1.15.15 - released on August 5, 2021 go1.15.14 - released on July 12, 2021 go1.15.13 - released on June 3, 2021 go1.15.12 - released on May 6, 2021 go1.15.11 - released on April 1, 2021 go1.15.10 - released on March 11, 2021 go1.15.9 - released on March 10, 2021 go1.15.8 - released on February 4, 2021 go1.15.7 - released on January 19, 2021 go1.15.6 - released on December 3, 2020 go1.15.5 - released on November 12, 2020 go1.15.4 - released on November 5, 2020 go1.15.3 - released on October 14, 2020 go1.15.2 - released on September 9, 2020 go1.15.1 - released on September 1, 2020 go1.15 - released on August 11, 2020 go1.14.15 - released on February 4, 2021 go1.14.14 - released on January 19, 2021 go1.14.13 - released on December 3, 2020 go1.14.12 - released on November 12, 2020 go1.14.11 - released on November 5, 2020 go1.14.10 - released on October 14, 2020 go1.14.9 - released on September 9, 2020 go1.14.8 - released on September 1, 2020 go1.14.7 - released on August 6, 2020 go1.14.6 - released on July 16, 2020 go1.14.5 - released on July 14, 2020 go1.14.4 - released on June 1, 2020 go1.14.3 - released on May 14, 2020 go1.14.2 - released on April 8, 2020 go1.14.1 - released on March 19, 2020 go1.14 - released on February 25, 2020 go1.13.15 - released on August 6, 2020 go1.13.14 - released on July 16, 2020 go1.13.13 - released on July 14, 2020 go1.13.12 - released on June 1, 2020 go1.13.11 - released on May 14, 2020 go1.13.10 - released on April 8, 2020 go1.13.9 - released on March 19, 2020 go1.13.8 - released on February 12, 2020 go1.13.7 - released on January 28, 2020 go1.13.6 - released on January 9, 2020 go1.13.5 - released on December 4, 2019 go1.13.4 - released on October 31, 2019 go1.13.3 - released on October 17, 2019 go1.13.2 - released on October 17, 2019 go1.13.1 - released on September 25, 2019 go1.13 - released on September 3, 2019 go1.12.17 - released on February 12, 2020 go1.12.16 - released on January 28, 2020 go1.12.15 - released on January 9, 2020 go1.12.14 - released on December 4, 2019 go1.12.13 - released on October 31, 2019 go1.12.12 - released on October 17, 2019 go1.12.11 - released on October 17, 2019 go1.12.10 - released on September 25, 2019 go1.12.9 - released on August 15, 2019 go1.12.8 - released on August 13, 2019 go1.12.7 - released on July 8, 2019 go1.12.6 - released on June 11, 2019 go1.12.5 - released on May 6, 2019 go1.12.4 - released on April 11, 2019 go1.12.3 - released on April 8, 2019 go1.12.2 - released on April 5, 2019 go1.12.1 - released on March 14, 2019 go1.12 - released on February 25, 2019 go1.11.13 - released on August 13, 2019 go1.11.12 - released on July 8, 2019 go1.11.11 - released on June 11, 2019 go1.11.10 - released on May 6, 2019 go1.11.9 - released on April 11, 2019 go1.11.8 - released on April 8, 2019 go1.11.7 - released on April 5, 2019 go1.11.6 - released on March 14, 2019 go1.11.5 - released on January 23, 2019 go1.11.4 - released on December 14, 2018 go1.11.3 - released on December 12, 2018 go1.11.2 - released on November 2, 2018 go1.11.1 - released on October 1, 2018 go1.11 - released on August 24, 2018 go1.10.8 - released on January 23, 2019 go1.10.7 - released on December 14, 2018 go1.10.6 - released on December 12, 2018 go1.10.5 - released on November 2, 2018 go1.10.4 - released on August 24, 2018 go1.10.3 - released on June 5, 2018 go1.10.2 - released on May 1, 2018 go1.10.1 - released on March 28, 2018 go1.10 - released on February 16, 2018 go1.9.7 - released on June 5, 2018 go1.9.6 - released on May 1, 2018 go1.9.5 - released on March 28, 2018 go1.9.4 - released on February 7, 2018 go1.9.3 - released on January 22, 2018 go1.9.2 - released on October 25, 2017 go1.9.1 - released on October 4, 2017 go1.9 - released on August 24, 2017 go1.8.7 - released on February 7, 2018 go1.8.6 - released on January 22, 2018 go1.8.5 - released on October 25, 2017 go1.8.4 - released on October 4, 2017 go1.8.3 - released on May 24, 2017 go1.8.2 - released on May 23, 2017 go1.8.1 - released on April 7, 2017 go1.8 - released on February 16, 2017 go1.7.6 - released on May 23, 2017 go1.7.5 - released on January 26, 2017 go1.7.4 - released on December 1, 2016 go1.7.3 - released on October 19, 2016 go1.7.2 - not fully released go1.7.1 - released on September 7, 2016 go1.7 - released on August 15, 2016 go1.6.4 - released on December 1, 2016 go1.6.3 - released on July 17, 2016 go1.6.2 - released on April 20, 2016 go1.6.1 - released on April 12, 2016 go1.6 - released on February 17, 2016 go1.5.4 - released on April 12, 2016 go1.5.3 - released on January 13, 2016 go1.5.2 - released on December 2, 2015 go1.5.1 - released on September 8, 2015 go1.5 - released on August 19, 2015 go1.4.3 - released on September 22, 2015 go1.4.2 - released on February 17, 2015 go1.4.1 - released on January 15, 2015 go1.4 - released on December 10, 2014 go1.3.3 - released on September 30, 2014 go1.3.2 - released on September 25, 2014 go1.3.1 - released on August 13, 2014 go1.3 - released on June 18, 2014 go1.2.2 - released on May 5, 2014 go1.2.1 - released on March 2, 2014 go1.2 - released on December 1, 2013 go1.1.2 - released on August 13, 2013 go1.1.1 - released on June 13, 2013 go1.1 - released on May 13, 2013 go1.0.3 - released on September 21, 2012 go1.0.2 - released on June 13, 2012 go1.0.1 - released on April 25, 2012 go1 - released on March 28, 2012 Pre-Go 1 Releases Go was publicly announed on November 10, 2009 ","date":"28 July 2022","permalink":"https://gosamples.dev/check-go-version/","section":"Tutorials","summary":"","title":"How to check your Go version"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/runtime/","section":"Tags","summary":"","title":"Runtime"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/version/","section":"Tags","summary":"","title":"Version"},{"content":"To repeat a given string in Go, you can use the strings.Repeat() function from the strings package.\nfunc Repeat(s string, count int) string\nIt takes a string and the number of times it should be repeated as arguments and returns the multiplied string as output. The function panics if count is negative or if len(s) * count overflows.\nLook at the following example:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;unicode/utf8\u0026#34; ) func main() { s := \u0026#34;gosamples.dev \u0026#34; repeated := strings.Repeat(s, 3) lineSeparator := strings.Repeat(\u0026#34;-\u0026#34;, utf8.RuneCountInString(repeated)) fmt.Println(repeated) fmt.Println(lineSeparator) } Output:\ngosamples.dev gosamples.dev gosamples.dev ------------------------------------------ In line 11, we create a new multiplied string which is the string \u0026quot;gosamples.dev \u0026quot; repeated three times. Then, in line 12, we want to make a line separator consisting of a repeated - character. Its length should be equal to the number of characters of the previous string.\nNote that we use the utf8.RuneCountInString() function to count the number of characters instead of len(). The former counts the runes (Unicode code points) in the string, while the latter counts the number of bytes. When counting characters in a string \u0026quot;gosamples.dev gosamples.dev gosamples.dev \u0026quot;, both functions will return the same number; however it is good to make a habit of using utf8.RuneCountInString() when you want to count the number of characters. It will prevent incorrect results when you change the input string:\ns := \u0026#34;€€€\u0026#34; fmt.Println(len(s)) fmt.Println(utf8.RuneCountInString(s)) 9 3 The € (euro) symbol is a three-byte character, encoded in UTF-8 with bytes 0xE2, 0x82, 0xAC.\n","date":"20 July 2022","permalink":"https://gosamples.dev/repeat-string/","section":"Tutorials","summary":"","title":"🔁 Repeat a string in Go"},{"content":"The time package in Go contains convenient functions for operating on Unix time (also known as Epoch time, Posix time, seconds since the Epoch, or UNIX Epoch time). Using them, you can easily get the current Unix timestamp, convert a time.Time struct to Unix time, and vice versa - Unix timestamp to time.Time. Check out this cheatsheet to learn how to do it and come back to it whenever you forget 😉\nConvert date/time to Unix epoch time #The time.Time struct contains Unix(), UnixMilli(), UnixMicro() and UnixNano() methods for converting a time object to a Unix timestamp of type int64.\ndate := time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC) fmt.Println(date.Unix()) fmt.Println(date.UnixMilli()) fmt.Println(date.UnixMicro()) fmt.Println(date.UnixNano()) Output:\n1654041600 1654041600000 1654041600000000 1654041600000000000 Get current Unix timestamp #To get the current Unix timestamp in Go, you just need to get the current time of type time.Time using the time.Now() function and convert it to Unix timestamp using Unix(), UnixMilli(), UnixMicro(), or UnixNano() method.\nGet current Unix/Epoch time in seconds # fmt.Println(time.Now().Unix()) Output:\n1657861095 Get current Unix/Epoch time in milliseconds # fmt.Println(time.Now().UnixMilli()) Output:\n1657861095093 Get current Unix/Epoch time in microseconds # fmt.Println(time.Now().UnixMicro()) Output:\n1657861095093115 Get current Unix/Epoch time in nanoseconds # fmt.Println(time.Now().UnixNano()) Output:\n1657861095093117000 Convert Unix timestamp to time.Time #The time package has three functions to convert from an int64 Unix timestamp to a time.Time object:\nUnix(sec int64, nsec int64) Time to convert a seconds timestamp, a nanoseconds timestamp, or timestamp with a seconds and nanoseconds part to a time.Time object. UnixMilli(msec int64) Time to convert from a millisecond timestamp to a time.Time. UnixMicro(usec int64) Time to convert a microsecond timestamp to a time.Time struct. Second Unix timestamp to time.Time # var timestamp int64 = 1657861095 t := time.Unix(timestamp, 0) fmt.Println(t.UTC()) Output:\n2022-07-15 04:58:15 +0000 UTC Millisecond Unix timestamp to time.Time # var timestamp int64 = 1657861095093 t := time.UnixMilli(timestamp) fmt.Println(t.UTC()) Output:\n2022-07-15 04:58:15.093 +0000 UTC Microsecond Unix timestamp to time.Time # var timestamp int64 = 1657861095093115 t := time.UnixMicro(timestamp) fmt.Println(t.UTC()) Output:\n2022-07-15 04:58:15.093115 +0000 UTC Nanosecond Unix timestamp to time.Time # var timestamp int64 = 1657861095093117123 t := time.Unix(0, timestamp) fmt.Println(t.UTC()) Output:\n2022-07-15 04:58:15.093117123 +0000 UTC Parse Unix timestamp from string to time.Time #To parse a string Unix timestamp and get a time.Time object, you must first convert the timestamp from string to int64, and then convert it to time.Time using the Unix(), UnixMilli(), or UnixMicro() function.\ntimeString := \u0026#34;1657861095\u0026#34; timestamp, err := strconv.ParseInt(timeString, 10, 64) if err != nil { panic(err) } t := time.Unix(timestamp, 0) fmt.Println(t.UTC()) Output:\n2022-07-15 04:58:15 +0000 UTC ","date":"18 July 2022","permalink":"https://gosamples.dev/unix-time/","section":"Tutorials","summary":"","title":"⌚ Unix time in Go [cheatsheet]"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/crud/","section":"Tags","summary":"","title":"Crud"},{"content":"","date":null,"permalink":"https://gosamples.dev/categories/data/","section":"Categories","summary":"","title":"Data"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/db/","section":"Tags","summary":"","title":"Db"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/gorm/","section":"Tags","summary":"","title":"Gorm"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/orm/","section":"Tags","summary":"","title":"Orm"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/pgx/","section":"Tags","summary":"","title":"Pgx"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/postgresql/","section":"Tags","summary":"","title":"Postgresql"},{"content":"To use PostgreSQL in Go, you need a database driver - a client that allows you to connect to and perform operations on the database. This comprehensive tutorial demonstrates three different approaches to working with PostgreSQL: using the standard database/sql package with the pgx driver, using the pgx client directly, and using the GORM ORM.\nClick here to go directly to the summary and full code examples.\nPure SQL or ORM #Before we start installing PostgreSQL and writing code, we need to decide which way of accessing the database we prefer.\nThe database/sql package #Go has a built-in universal interface for operating on SQL databases in the database/sql package. Since this package provides universal functions, we need another component, a driver, to make it work for a particular database. The driver is a package compatible with the database/sql/driver interface and provides direct access to the database. In other words, a driver is a client of a specific database in Go, compatible with the database/sql/driver interfaces, and thanks to that, it can be used by the database/sql package.\nThe advantage of database/sql is its simplicity and versatility. If you want to start working with a new SQL database, you will almost certainly find an open source, well-tested driver for it. They are all compatible with the database/sql, so if you would like to swap one database for another, then all you need to do is replace the driver with little or no changes.\nAlso, working with the database/sql is about writing pure SQL commands, getting results from functions, and converting them to a specific format. You have to do all these steps by yourself. So if you want full control over the whole process of reading or writing data to a database, then the database/sql is a great choice.\nA database client #Since the database/sql package is universal and offers the same functionality for all databases, you may be wondering how to use the specific features of a given database in Go.\nFor such cases, many databases provide a custom client package. Such a package is something like a non-standard driver extended with all the functionality of the database. Typically, clients are low-level, and because they are dedicated to a particular database, they can be faster than database/sql compatible drivers. So if you do not need the versatility that database/sql offers but rather specific database features, then using a dedicated client may be a good choice.\nAn ORM or other tools #The database/sql package and dedicated clients run at a low level, and not everyone likes this type of work. Especially if the database you want to implement has many tables, you expect some sort of speedup by not having to write every query by hand. In this case, the best solution would be to use ORM or other tools, such as those that generate code from SQL commands.\nORMs are packages that make things easier by providing automatic Struct-Table mapping and no need to write error-prone pure SQL statements. They often have features not included in the standard database/sql library, such as automatic migration, caching, pagination of results, and many others. They speed things up at the expense of a higher level of abstraction and less control over the data you get.\nHowever, if you prefer to operate on SQL queries but still want to get some speedup over database/sql, a good solution is to use a code generator such as sqlc. It works by generating type-safe code from SQL: you write SQL commands, run sqlc, get a model, and well-defined Go functions that read from or write to the database.\nWhat we are going to use #In this tutorial, we are going to show you three approaches to creating a database access layer. First, using the pgx PostgreSQL database/sql compatible driver as this is the simplest and most natural approach for Go. Second, using the pgx custom client that offers all the features of PostgreSQL in Go. As a bonus, we will also show you how to create the same functions using GORM ORM. As a complete Go programmer, you should know all these approaches and use the best one for a given use case.\nRead more about the pgx driver and toolkit package, GORM, and other drivers and ORMs in our list of the best drivers and ORMs for PostgreSQL in Go.\nRepository pattern #Clean and maintainable projects require the presentation, application, and persistence layers be kept separate from each other. No one likes spaghetti code that mixes bits of direct data retrieval and bits of data processing. In our opinion, only two things are needed to create a clean design in terms of data.\nFirst of all, the code that retrieves and writes data to the database for a given Domain object should be extracted as a separate service so that there is only one place to access the domain object data in the entire project - the data access layer.\nSecond, database implementation details should be hidden behind an abstraction - an interface. This approach keeps the code database-independent and resilient to future changes in the infrastructure, since one database can easily be replaced in the code by another by creating a new implementation of the same interface for a new database. In addition, working on interfaces rather than a specific implementation helps you focus on the domain rather than on how the data is stored.\nBoth of these things can be achieved by using the Repository pattern. It focuses on abstracting the data access layer and separating data storage from the specific database implementation.\nIn this tutorial we will show you how to create the correct data access layer using this design pattern.\nSome people think there is no point in using a design pattern like Repository if your project is small. However, we strongly recommend using this pattern for any project that will work in a production environment. Adapting to changes is part of a programmer\u0026rsquo;s job, and with the Repository pattern and the loose coupling between the database part and the business logic, any code change is easier.\nInstall PostgreSQL #After defining the basic assumptions about the project, it is time to install PostgreSQL.\nThe most convenient and fastest way is to run the PostgreSQL instance as a Docker container. If you are not familiar with Docker, check out the documentation here and how to get Docker here.\nIf you want to install PostgreSQL directly on your machine, check out the instructions on the official PostgreSQL site.\nThe command on the right starts the PostgreSQL database instance inside a Docker container.\nWhat we are going to build #As part of our introduction to PostgreSQL in Go, we will create a mini ranking of websites that we will store in the database. So, Website will be our domain object. In addition to creating and reading objects from the database, we also want to be able to delete and update Website records. Therefore, the application we will make should perform all CRUD (create, read, update, delete) operations.\nDatabase operations will be defined in the Repository interface you have seen before. We will create three concrete implementations of this interface - the first using the database/sql package, the second using the pgx client package, and the third using the GORM ORM.\nInit project structure #So let\u0026rsquo;s start creating our project. Open Terminal and create a new directory named postgresql-intro in a location of your choice.\nmkdir postgresql-intro Go to the directory:\ncd postgresql-intro and create a new Go module for our project:\ngo mod init postgresql-intro Then create three new directories in the postgresql-intro project:\nmkdir cmd mkdir website mkdir app Domain object and repository #The next step is to define the domain object and the repository. In the website package, create two new files: website.go and repository.go, and copy their contents that you can see on this page into them.\nA Website is a struct that contains simple data about the website - its name, URL, position in the ranking, and numeric identifier. Objects of this type will be stored and retrieved from the database.\nThe Repository is our interface for reading and writing Website data from and to the database. Note that the methods of this interface do not depend on PostgreSQL at all. This is one of the main goals of the Repository pattern - hiding database implementation details and providing a simple API to interact with any database.\nAfter the changes, the project structure should look like this:\npostgresql-intro ├── app ├── cmd ├── go.mod └── website ├── repository.go └── website.go We will go through what each method does in the next step, but by now, you may be wondering why every method signature has ctx context.Context in the parameter list.\nIn short, the context.Context is an object that is a common Go concept used by web applications to send request-scoped values, cancellation, and deadline signals to deeper layers of services. Let\u0026rsquo;s assume that in your application you want to wait a maximum of 5 seconds for a response from the database to prevent the application to wait idly if there are any connection problems. To ensure this, you can create a new Context with a defined timeout of 5 seconds. The functions of a client or driver operating directly on the database, while receiving such a Context, respect it, which means that after the timeout of 5 seconds is exceeded, the connection is interrupted, and the application can continue to run.\nIn our demo application, we will also use this feature and set a timeout for all operations using the context.Context.\nRepository methods #Our repository functions perform migration and basic CRUD operations:\nMigrate(ctx context.Context) error - The method responsible for migrating the repository, i.e., adjusting the PostgreSQL table to the domain object and importing the initial data. In our case, this function will be responsible for creating a new websites table. So there is no need to log into the GUI database client and manually create the table. However, it is important to remember that this function should be executed first, before reading or writing to the database. Create(ctx context.Context, website Website) (*Website, error) - Method that creates a new website record in the repository. It returns the website saved to the database with the generated ID or an error in case of problems. All(ctx context.Context) ([]Website, error) - It extracts all records from the repository and returns as a slice or returns an error if there are problems. GetByName(ctx context.Context, name string) (*Website, error) - Gets a single Website record with the specified name or returns an error if there are problems. The name of each Website must be unique, so there is no risk of having two records with the same name. Update(ctx context.Context, id int64, updated Website) (*Website, error) - Updates the Website record with the id identifier with the values found in the updated struct. It returns the updated record or an error in case of problems. Delete(ctx context.Context, id int64) error - Deletes a record with the id identifier and returns an error if there are problems. As you can see, all of these methods return errors. Some of them may be due to the action of the user, for example, when someone tries to add a Website that already exists (with the same name). It is a good practice to define such errors and return them from the functions so that the application can handle them and respond with an appropriate error message to the user. We will do this on the next page.\nRepository errors #Add the error definitions to the website/repository.go file and let\u0026rsquo;s analyze them:\nAn ErrDuplicate error means that the user is trying to add a record that already exists, i.e., with the same name, because in our repository, we assume that each website should have a unique name. This error should be returned from the methods that write to the database - Create() or Update() when a violation of the uniqueness constraint is detected. An error ErrNotExist means no record with the specified parameters in the database. This should be returned from any functions that pull a single object from the repository. In our case, this is the GetByName() method. An ErrUpdateFailed error is an error returned by the Update() method. It should appear when no row has been affected by the requested update, such as when the change was to a row with a non-existent id. An ErrDeleteFailed error should occur when no row was deleted as a result of executing the Delete() method, e.g., because there is no row with the given id. Of course, when using the repository, a whole bunch of other errors can also occur, e.g., network errors, connection failures, timeouts, etc. However, these are unexpected errors, and not every application needs to handle them in a special way. But user errors like the above should always be handled so that the user can react and correct bad input.\nInit classic database/sql repository #Now is the time to implement your first PostgreSQL repository. We will start with a repository based on the classic database/sql package. In the website package, create a new file repository_postgresql_classic.go and copy the code of the repository structure PostgreSQLClassicRepository with its constructor and the Migrate() method.\nYou may wonder why we named the file repository_postgresql_classic.go when inside we have a PostgreSQLClassicRepository struct. Why is the name not postgresql_classic_repository.go? Well, this way of naming helps in locating repository files in the IDE more easily. Take a look at the project tree:\npostgresql-intro ├── app ├── cmd ├── go.mod └── website ├── repository.go ├── repository_postgresql_classic.go └── website.go The files are sorted by name, so the repository_postgresql_classic.go is next to the repository.go file, and so all other future repository variants will be next to each other thanks to this naming style.\nLocating specific files in a package can be difficult when the package contains a lot of files, so it is a good idea to take care of the naming convention that will help with this from the beginning of the project.\nIn the next parts, we will be using the pgx driver objects, so we need to add this package to the project. Run the go get command in our project directory:\ngo get github.com/jackc/pgx/v4 and\ngo get github.com/jackc/pgconn to get the low-level package internally used by the pgx.\nNow you are ready to understand what we just added and develop the project further.\nThe repository constructor #In lines 8-16, we define the PostgreSQLClassicRepository struct and its NewPostgreSQLClassicRepository() constructor. It accepts only one dependency as an argument: sql.DB, which represents the database connection pool for all drivers compatible with the database/sql interface. Using sql.DB, we will perform direct database operations in the repository methods.\nMigrate() method #As we already mentioned, the Migrate() function in our project is used to create a schema for the websites table where we will store our data. Using the DB.ExecContext() method, we execute a SQL query that creates the table. Note that we use here a variant with passing the context.Context (there is also an analogous DB.Exec() function that omits the context), which will allow us to stop the execution of the query, for example, in case of a timeout.\nImplement Create method #We have already created the repository structure and the Migrate() method, so it is time to implement the \u0026ldquo;C\u0026rdquo; from the CRUD abbreviation, which is the Create() function. Copy the code for this method into our classic repository file and make sure you have all the necessary imports.\nCreate() method #The Create() function takes the website given as an argument and inserts it into the table. Generally, the DB.Query*() methods of the DB struct are used for reading the data from the database, and DB.Exec*() for inserts, updates, and deletes. So you may wonder why we use the DB.QueryRowContext() method for insertion instead of DB.ExecContext(). To explain that, look at the last part of the INSERT query:\nRETURNING id It causes the query to return the id of just inserted record as a result, which needs to be read using the Scan() method of the Row object returned by the DB.QueryRowContext().\nerr := r.db.QueryRowContext(ctx, \u0026#34;INSERT INTO websites(name, url, rank) values($1, $2, $3) RETURNING id\u0026#34;, website.Name, website.URL, website.Rank).Scan(\u0026amp;id) With the DB.ExecContext(), we would not be able to get the id of the last inserted record. This function returns a Result object (and an error) that has the LastInsertId() method, but due to the specific behavior of the INSERT command in PostgreSQL, this method is not supported by the pq and pgx drivers. More information here.\nNote how we pass arguments to the INSERT query. We use the symbols $1, $2, $3, which at the execution stage are replaced with the values in the first, second, and third place after the SQL query in the DB.QueryRowContext() function. This way is supported by PostgreSQL and much safer in terms of defending against SQL injection attacks than using the fmt.Sprintf() function to build the final query.\nAfter executing the INSERT command, we check if an error has occurred. If so, we check if it is an instance of the pgconn.PgError error and if its code indicates the unique constraint violation (code 23505). Such an error means that a row with the same UNIQUE field already exists in the table. For the websites table it means that a website with the same Name already exists. In this case, we can map the internal PostgreSQL error pgconn.PgError to the general Repository error ErrDuplicate, which we defined earlier. As the last thing, we assign the ID of the inserted item to the object that will be returned from the Create() function so that it reflects the current state in the database.\nImplement reading methods #Now, we are going to implement the reading methods: All() and GetByName(). Let\u0026rsquo;s add them to the repository_postgresql_classic.go file.\nAll() method #The All() method returns all rows from the websites table. It uses the DB.QueryContext() method to get the rows for a SQL SELECT query. It returns them in the form of an sql.Rows object, which represents a cursor to the DB rows. It is important to remember that after you finish working with the sql.Rows object, it should be closed, which is what the line below does (defer keyword means that the rows.Close() will be called at the end of the All() method):\ndefer rows.Close() Using the Rows.Next() method in the loop, which returns true if there are any more rows in the sql.Rows object, and the Rows.Scan(), which copies the successive row values to the given variables, we can convert the raw data from the database into a slice of Website objects. Note that in case of any error in retrieving or copying the data, the whole procedure is interrupted, and an error is returned. If successful, the All() method returns a slice of Website objects.\nGetByName() method #The GetByName() function retrieves one Website record with the name given as an argument. It works similarly to All(), except that instead of using the DB.QueryContext() method, it uses DB.QueryRowContext(), which returns at most one row in the form of sql.Row, and there is no need to close it. To copy the raw values to the Website object, the same Scan() function is used as before, except that in case of an error, we check if it is an instance of sql.ErrNoRows indicating no results. If such an error appears, we map it to our predefined repository error ErrNotExist. So if a user makes a mistake and, as an argument, he passes a website name that is not in the database, he will receive a clear error indicating the reason.\nImplement Update method #Our repository should also be able to update an existing row. This is what the Update() method is for. Copy it into the code of our repository.\nUpdate() method #The Update() method updates the record with the specified id. It is not significantly different from other methods you have seen before.\nFirst, we execute the SQL UPDATE query using the DB.ExecContext(), which updates the values of all columns of the websites table row. During the update, there may be a situation where the value of the updated field name already existed in the database, in which case a unique constraint violation error will occur. We handle such an error in the same way as in the Create() function.\nFinally, we get the value of the RowsAffected() function from the returned sql.Result object to see how many rows were affected by our change. If 0, this indicates an error during the update, such as an invalid id was passed as an argument. We return this information to the user in the form of an ErrUpdateFailed error we defined earlier. If everything is fine, we return the updated Website object.\nImplement Delete method #The last letter in the CRUD abbreviation, D, stands for Delete() function. Add its code to the repository.\nDelete() method #The Delete(), as the name suggests, deletes a record with the given id from the database. As in the Update() method, to execute the SQL DELETE command, we use the DB.ExecContext() function and also check whether the number of affected rows is equal to 0. If so, it means a delete error, which we return as a previously defined ErrDeleteFailed error.\nThis way, we have finished creating our first repository based on the classic database/sql package. In the next step, we will make a test procedure and an application to check in practice what we have written.\nInit the main function and the demo procedure #Demo procedure #Let\u0026rsquo;s start by initializing a test procedure that will perform a series of actions on the repository. After executing each function, we will check the results by writing them to the standard output or check if there was an error.\nCreate the app/demo.go file in the demo package we created at the beginning of the project and copy its contents.\nThe RunRepositoryDemo() function takes as arguments the context used in the repository methods and the repository itself. Note what type websiteRepository has. It is the website.Repository, which is our repository interface. This way, the RunRepositoryDemo() function can be used with any repository implementation, which is what we are going to do in the next steps. For now, this function does only one thing - it calls the Migrate() method to create our storage for Website objects.\nThe main() function #We already have the repository implementation and the first version of the demo procedure, so we can put everything together and run a test application.\nCreate a new directory classic in the cmd package for the application that demonstrates the classic repository based on the database/sql package. Add a new file main.go to the classic directory. This is our executable file. Copy the contents of the cmd/classic/main.go to your newly created main.go. Run our test app with ```shell go run main.go If everything went well, the program should exit without error, and a new table called `websites` with columns: `id`, `name`, `url`, and `rank` should be created in the PostgreSQL database. ### What does the `main()` function do? #### Connect to PostgreSQL database To connect to a PostgreSQL database using the [`pgx`](https://github.com/jackc/pgx), it is necessary to register it as a [`database/sql`](https://pkg.go.dev/database/sql) driver. This is done by importing the driver package in line `11`. By using a blank identifier, we import the package, even if it is not used by the current program. Once imported, it calls the internal [`init()`](https://go.dev/doc/effective_go#init) function, which registers the driver in the [`database/sql`](https://pkg.go.dev/database/sql) interface under the name `pgx`. \u0026gt; The [`pgx`](https://github.com/jackc/pgx) has a [`database/sql`](https://pkg.go.dev/database/sql) compatible driver in the package [github.com/jackc/pgx/v4/stdlib](https://github.com/jackc/pgx/tree/master/stdlib). In lines `15-19`, we use the registered driver. Using the [`sql.Open()`](https://pkg.go.dev/database/sql#Open) function with the `pgx` as the first argument, we connect to the PostgreSQL database. The second argument is the `dataSourceName` consisting of the connection information. For PostgreSQL, we define the so-called [connection URI](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) here. In our case, we are connecting to the database named `website` located on `localhost` on port `5432` with username `postgres` and password `mysecretpassword` because this is what we set at the stage of [running the Docker image](../install-postgresql). The result is the [`sql.DB`](https://pkg.go.dev/database/sql#DB) object (and an error if it occurs) safe for concurrent use and maintaining its own pool of idle connections. A good practice is to close the DB connection at the end of the program with the [`Close()`](https://pkg.go.dev/database/sql#DB.Close) method. #### Create a `Website` repository, context, and run the demo procedure In line `21`, we call a constructor of the `PostgreSQLClassicRepository` with the created [`sql.DB`](https://pkg.go.dev/database/sql#DB) object as an argument. Then, we initialize a new [`Context`](https://pkg.go.dev/context#Context) object with a 10-second timeout using the [`context.WithTimeout()`](https://pkg.go.dev/context#WithTimeout) function. Its first argument is a parent [`Context`](https://pkg.go.dev/context#Context) which in our case is an empty fresh [`Context`](https://pkg.go.dev/context#Context) instance obtained from the [`Background()`](https://pkg.go.dev/context#Background) function. Note that in addition to the [`context.Context`]((https://pkg.go.dev/context#Context)) object, as a result, we also get a [`cancel()`](https://pkg.go.dev/context#CancelFunc) function to release the resources associated with the context, so we do this at the end of the program as soon as all operations using the context have finished: ```go defer cancel() In the last line of the main(), we call our demo procedure passing the created context and our classic database/sql repository as arguments.\nComplete the demo procedure #We already have a working application using the repository implementation and calling the demo procedure. However, it would be good for the demo procedure to do more than just migrate data. So complete the app/demo.go file, and let\u0026rsquo;s trace what the newly added operations do.\nMIGRATE REPOSITORY - As you already know, at the beginning, we executed the Migrate() function, which created the websites database table. CREATE RECORDS OF REPOSITORY - Next, in lines 18 to 43, we create 2 new Website objects and add them to the repository using the Create() method. Then we print out the inserted records to the standard output. Note how we handle errors from the Create() method. In the case of an ErrDuplicate error, we only log that fact; in the case of a non-standard, unexpected error, we abort the application execution by logging the error using the log.Fatal() function. GET RECORD BY NAME - After inserting the records to the database, we check if we can pull them from there. In lines 45-53, we get a record named GOSAMPLES using the GetByName() method. If such a row does not exist, we log an ErrNotExist error and move on. Other unknown errors are logged, and the application exits. UPDATE RECORD - In lines 55-65, we update a single record with a new ranking value. Because the Update() method may return ErrDuplicate or ErrUpdateFailed errors, we check for them and handle them by printing on the standard output. GET ALL - Lines 67 through 75 use the All() method to get a list of all records and then print them to the standard output, so we can check that the update actually was made in the database. DELETE RECORD - In lines 77-84, we delete one of the inserted records and handle errors if they occur. In the case of ErrDeleteFailed, we log the error; in the case of others, we exit the application. GET ALL - As the last thing, in lines 86-93, we again get the list of all records using the All() method and write them out to the standard output to check if the row was actually deleted. Now you can run our cmd/classic/main.go application using\ngo run main.go and check the output:\n1. MIGRATE REPOSITORY 2. CREATE RECORDS OF REPOSITORY \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} \u0026amp;{ID:2 Name:Golang official website URL:https://golang.org Rank:1} 3. GET RECORD BY NAME \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} 4. UPDATE RECORD 5. GET ALL {ID:2 Name:Golang official website URL:https://golang.org Rank:1} {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} 6. DELETE RECORD 7. GET ALL {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} Feel free to experiment on your own. If this is your first application connecting to PostgreSQL, change function input arguments, change data, run the application multiple times and see what happens, check what errors appear, and try to fix them. The code we have created is just an introduction, which you should use as a base to create something more advanced.\nRemember that when you run the application for the second time, you have already inserted data into the websites table. If you want to clean the database, just close the running PostgreSQL Docker container and restart it using docker run as in the beginning.\nThis way, we finished building the application that performs CRUD operations using the repository based on the database/sql package. In the following pages, we will show you how to create a repository based on the pgx client package, and using an ORM called GORM.\nRepository based on the pgx client #As we know, the pgx package, in addition to the database/sql compatible driver, also has its own DB client, which is faster and has more features, so it is even more recommended than the classic driver.\nLet\u0026rsquo;s add a repository based on this client. Create a new file repository_postgresql_pgx.go in the website package. Then copy its contents, and let\u0026rsquo;s trace how such a repository differs from the one we previously created.\nTo use the pgxpool package, we need to add it to our project:\ngo get github.com/jackc/pgx/v4/pgxpool This repository is very similar to our classic database/sql based repository. It differs actually only in two things:\nInstead of using the sql.DB to connect with the database, we use a pgxpool.Pool object here. Like sql.DB, it represents a pool of connections to a database and is concurrency safe. All the database methods we use are practically the same as in database/sql based repository, except that you always have to pass context.Context and there is no version without context. So we have the Query() method instead of QueryContext(), Exec() instead of ExecContext(), etc. Using pgx client is therefore not significantly different from using a database/sql compatible driver. The authors of pgx recommend this way of connecting to PostgreSQL but explain in more detail when to choose which version here.\nRun the demo procedure for pgx-based repository #To run our demo procedure with the created pgx client-based repository, we need to make a new app. Create a new pgx directory in the cmd and add a new main.go file.\nAs you can see in the code, the main.go file, in this case, is also very similar to the version with the classic repository. The difference is the initialization of the pgxpool.Pool instead of the sql.DB, but note that we are using the same connection string as before and also have to take care of closing the connection at the end. Also, in imports section, you does not have to import the database/sql compatible driver. The rest of the code is analogous to the classic version.\nRemember that our previous application has already inserted data into the websites table. So to clean the database, just close the running PostgreSQL Docker container and restart it using docker run as in the beginning.\nIf you run the cmd/pgx/main.go, you will see the same output as for the cmd/classic/main.go:\n1. MIGRATE REPOSITORY 2. CREATE RECORDS OF REPOSITORY \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} \u0026amp;{ID:2 Name:Golang official website URL:https://golang.org Rank:1} 3. GET RECORD BY NAME \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} 4. UPDATE RECORD 5. GET ALL {ID:2 Name:Golang official website URL:https://golang.org Rank:1} {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} 6. DELETE RECORD 7. GET ALL {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} GORM repository #The last repository we want to create in this tutorial is a repository based on the ORM package GORM. Create a new file repository_postgresql_gorm.go in our domain package website and copy the contents of the repository there.\nYou will need the gorm.io/gorm package to make everything work, so add it to your project:\ngo get gorm.io/gorm Let\u0026rsquo;s go through what our repository looks like.\nCheck out GORM great documentation if you want to learn more about how to use it.\nThe gormWebsite structure #GORM is based on models, i.e., structs that represent a database row and describe the table schema using struct tags. In our repository, we have defined the gormWebsite model, which describes the structure of the websites table. Look at how the struct tags define the table columns, and the TableName() method sets the table name. As you can probably guess, since the entire table is defined in code, we do not have to use SQL to perform operations on the database, even to create the table.\nIf you want to learn more about declaring models in GORM, check out the documentation.\nThe repository constructor #The repository structure PostgreSQLGORMRepository (and the constructor NewPostgreSQLGORMRepository) takes only one argument, the gorm.DB object that represents, as in the previous cases, a concurrent safe connection to the database.\nMigrate() method #GORM has the AutoMigrate() method to perform automatic migration, which is, creating or modifying a table schema as defined in the model struct. Look at the line 34. We create a database object that respects the passed context.Context using the WithContext() function, and then call the AutoMigrate() method with the model object as an argument. It is enough to create websites table in the database with the columns defined in the model.\nCreate() method #To insert records into a DB table, we can use the GORM DB.Create() method, which takes a model object as an argument. Since we are operating on a domain object of type Website, we should remember to convert it to gormWebsite, which we do in lines 38-42. After successfully inserting the record, the GORM function DB.Create() also updates the value of the inserted object with the generated ID. So we just need to convert the inserted value back to Website (line 54) and return this object from our Create() method as an inserted Website record. In this method, as with previous repository implementations, we also handle the unique constraint violation error. Since the PostgreSQL driver for GORM internally uses the pgx package, all we need to do is check that we get an appropriate error of type pgconn.PgError.\nAll() method #To get all the records from the table, we just need to initialize an empty slice of gormWebsite objects for results and set it as an argument to GORM\u0026rsquo;s Find() method (line 61). Then, to be able to return a slice of type []Website, the result needs to be converted, which we do in lines 65-68.\nGetByName() method #The GetByName() method is very similar to All() except that we use the GORM Where() function to add the SQL WHERE clause to our query, and we handle the gorm.ErrRecordNotFound error that is returned when there is no record with the given criteria. Note that the GORM requires ? instead of $1 as a placeholder in the Where() query. As with the All() method, we use the Find() function here to get the result, but this time with a single gormWebsite object as an argument. In the end, we convert the result to our Website domain object.\nUpdate() method #If you have followed the previous methods, then Update() is nothing new for you. We use the GORM Save() function here to update the value of a gormWebsite object in the database. Finally, in addition to checking that we did not create a duplicate by updating, we also get the number of rows affected by this change. If it is equal to 0, we return the ErrUpdateFailed error, as in previous repository implementations.\nDelete() method #To delete a record, we use the GORM Delete() function in a variant that removes a row with the specified primary key. If no row has been affected by the delete, we return the ErrDeleteFailed error.\nRun the demo procedure for GORM repository #To run our demo procedure for the GORM repository, create a new gorm directory in cmd and put a new main.go file in it. Then copy the code there, most of which you should already know well.\nIn the main() function, we do almost the same as in the previous applications: open the connection to the DB, create the repository, and run the demo procedure. The main difference is in the initialization of the database connection. GORM has a function gorm.Open() which opens the DB using a set SQL dialect. In our case, we want to use the PostgreSQL dialect, so we create it using the GORM\u0026rsquo;s PostgreSQL driver function postgres.Open() with the same connection string as in the previous apps. The postgres driver is a separate package, and be sure to add it to our project:\ngo get gorm.io/driver/postgres In the main(), we open the connection in the simplest way, but GORM has a lot of configuration options. You can read about them here.\nThen, we create a new GORM Website repository (PostgreSQLGORMRepository) and run our demo procedure. The output should be the same as for the previous apps.\nRemember that our previous applications have already inserted data into the websites table. So to clean the database, just close the running PostgreSQL Docker container and restart it using docker run as in the beginning.\n1. MIGRATE REPOSITORY 2. CREATE RECORDS OF REPOSITORY \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} \u0026amp;{ID:2 Name:Golang official website URL:https://golang.org Rank:1} 3. GET RECORD BY NAME \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} 4. UPDATE RECORD 5. GET ALL {ID:2 Name:Golang official website URL:https://golang.org Rank:1} {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} 6. DELETE RECORD 7. GET ALL {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} As always, we encourage you to experiment, change the code, see what comes out, get errors and find their solution.\nSummary #Finally, we have reached the end of our tutorial. We presented in it how to connect to PostgreSQL from the Go language using three different approaches, how to perform CRUD operations and how to create a well-structured data access layer using clean code practices and the Repository design pattern.\nIt was just an introduction to give a general overview of what an application\u0026rsquo;s integration with the PostgreSQL database should look like. However, with these basics, you can create much more advanced projects being sure that they are robust to any future changes.\nGood luck!\nThe project code #The full code of the project created in this tutorial is available on Github here.\n","date":"12 July 2022","permalink":"https://gosamples.dev/postgresql-intro/","section":"Tutorials","summary":"","title":"PostgreSQL in Go: Complete Tutorial with database/sql, pgx, and GORM"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/repository/","section":"Tags","summary":"","title":"Repository"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/sql/","section":"Tags","summary":"","title":"Sql"},{"content":"If you want to make a title from your string in Go, i.e., make the first letter of each word in the string uppercase, you need to use the cases.Title() function from the golang.org/x/text/cases package. The function creates a language-specific title caser that capitalizes the first letter of each word.\nAlso check out how to convert an entire string to uppercase here.\nLook at the example below. We create a new generic title caser using undefined language language.Und. If you are sure that your strings are in a specific language, you can set it, for example, language.English, language.German, etc. Next, we transform the string using the created caser with the Caser.String() method. The result is a string where the first letter of each word is capitalized, and the remaining letters are lowercase.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/text/cases\u0026#34; \u0026#34;golang.org/x/text/language\u0026#34; ) func main() { fmt.Println(cases.Title(language.Und).String(\u0026#34;goSAMples.dev is the best Go bLog in the world!\u0026#34;)) } Output:\nGosamples.dev Is The Best Go Blog In The World! If you want to disable the lowercasing of non-leading letters, use the cases.NoLower option as the second parameter of the cases.Title() function.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/text/cases\u0026#34; \u0026#34;golang.org/x/text/language\u0026#34; ) func main() { fmt.Println(cases.Title(language.Und, cases.NoLower).String(\u0026#34;goSAMples.dev is the best Go bLog in the world!\u0026#34;)) } Output:\nGoSAMples.dev Is The Best Go BLog In The World! ","date":"25 May 2022","permalink":"https://gosamples.dev/uppercase-first-letter/","section":"Tutorials","summary":"","title":"🥇 How to uppercase the first letter of each word in Go"},{"content":"To convert a string to uppercase in Go, use the strings.ToUpper() function. It returns a copy of the input string, in which all letters are uppercase. The function is part of the built-in strings package used for manipulating UTF-8 encoded strings.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { fmt.Println(strings.ToUpper(\u0026#34;https://gosamples.dev\u0026#34;)) } Output:\nHTTPS://GOSAMPLES.DEV If you want to uppercase only the first letter of each word, see our other example here.\nIf your string is in a language with the special casing rules, for example, Turkish or Azeri, use the strings.ToUpperSpecial() function. This function takes a case mapping as its first parameter, with which it converts the string into uppercase.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;unicode\u0026#34; ) func main() { fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, \u0026#34;en iyi web sitesi\u0026#34;)) } Output\nEN İYİ WEB SİTESİ ","date":"25 May 2022","permalink":"https://gosamples.dev/string-to-uppercase/","section":"Tutorials","summary":"","title":"🔠 String to uppercase in Go"},{"content":"When you start a new project in Go, you probably always ask yourself about the data access layer. Use the generic database/sql interface and write queries by hand or use an ORM package, or tools to help generate queries? Which database driver to use? What packages to use to make your workflow fast and smooth? In this post we will try to review the best available drivers and ORM packages for the PostgreSQL database. Unfortunately, there are a lot of them, and they are all good enough, so the choice will not be easy, and you have to decide what is the most important for you 😉.\nDrivers #1. pgx #Recommended driver for a new project, actively maintained and developed. Low-level, fast, and performant. It consists of two components: driver and toolkit. The driver is compatible with the database/sql interface, while the toolkit contains PostgreSQL-specific features and functionalities that make your work easier, such as mapping between PostgreSQL and Go.\nGithub: https://github.com/jackc/pgx\nPackage documentation: pgx\n2. pq #Historically the most popular PostgreSQL driver for Go. Well tested and used in many existing projects. Currently only in the maintenance mode. As the authors themselves say:\n\u0026ldquo;For users that require new features or reliable resolution of reported bugs, we recommend using pgx which is under active development.\u0026rdquo; \u0026ndash; pq maintainers\nHowever, if you are looking for a battle-tested and stable driver for Go, the pq is a great choice.\nGithub: https://github.com/lib/pq\nPackage documentation: pg\nORMs #1. GORM #One of the most popular ORM packages in Go, whose the main goal is to be developer-friendly. Officially supports PostgreSQL, MySQL, SQLite, and MSSQL. It is actively developed, has great documentation, and many features, like:\nStruct - Table mapping support Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism, Single-table inheritance) Hooks (Before/After Create/Save/Update/Delete/Find) Eager loading with Preload, Joins Transactions, nested transactions, Save Point, RollbackTo to Saved Point Context, prepared statement mode, DryRun mode Batch Insert, FindInBatches, Find/Create with map, CRUD with SQL Expr and Context Valuer SQL Builder, Upsert, Locking, Optimizer/Index/Comment Hints, Named Argument, SubQuery Composite Primary Key, Indexes, Constraints Auto migrations and many more Website: https://gorm.io\nGithub: https://github.com/go-gorm/gorm\nPackage documentation: GORM\n2. Bun #Bun is a SQL-first ORM that provides an ORM-like experience using good old SQL. It supports PostgreSQL, MySQL, MariaDB, MSSQL, and SQLite. Great documentation and essential features, useful in everyday work are its strong points:\nBulk inserts Bulk updates Bulk deletes Fixtures - load initial data into a database for testing or demonstration purposes using YAML files Migrations Soft deletes Website: https://bun.uptrace.dev\nGithub: https://github.com/uptrace/bun\nPackage documentation: Bun\n3. ent #An entity framework for Go. It is the ORM developed by Facebook focusing on graph-based data models. The schema is defined as a graph structure in Go code, from which the model and operations are generated using code generation. It supports PostgreSQL, MySQL, MariaDB, TiDB, SQLite, and Gremlin.\nWebsite: https://entgo.io\nGithub: https://github.com/ent/ent\nPackage documentation: ent\n4. upper/db #A data access layer made for productivity. API is compatible with SQL and NoSQL databases like PostgreSQL, MySQL, MSSQL, CockroachDB, MongoDB, QL, and SQLite. It provides an agnostic API focused on working with collections of items, a SQL builder for more direct access to the database, and an ORM-like layer for mapping between a struct and a database table and working with the database in a more ORM-like style. Some features:\nStruct - Table Mapping Support Search and delimitation of result sets Limit-offset pagination (page numbers) Cursor-based pagination (previous and next) Transactions support Website: https://upper.io\nGithub: https://github.com/upper/db\nPackage documentation: upper/db\n5. XORM #Simple and powerful GORM alternative supporting PostgreSQL, MySQL, SQLite, MSSQL, MariaDB, TiDB, CockroachDB, and Oracle. Some of the features:\nStruct - Table mapping support Transactions support Synchronization of database schema Query cache Database Reverse - tool that generates code from the database schema Simple cascade loading Optimistic Locking support SQL Builder and many more Website: https://xorm.io/\nGitea: https://gitea.com/xorm/xorm\nPackage documentation: XORM\n6. POP #It is part of the Buffalo Go web framework, deeply integrated, and recommended when using Buffalo. But can also be used as a stand-alone data access layer. POP follows conventions influenced by the ActiveRecord Ruby gem making it easy to do CRUD operations with basic ORM functionality, run migrations, and build/execute queries. It supports PostgreSQL, CockroachDB, MySQL, and SQLite databases.\nWebsite: https://gobuffalo.io/documentation/database/pop\nGithub: https://github.com/gobuffalo/pop\nPackage documentation: POP\n7. REL #REL is a modern ORM-ish data access layer for layered architecture. It is built with testability in mind and comes with its custom test library. It supports PostgreSQL, MySQL, MSSQL, and SQLite. Features:\nTestable repository Nested transactions Query builder Eager loading support Composite Primary Key Soft deletes Pagination Schema Migration Website: https://go-rel.github.io\nGithub: https://github.com/go-rel/rel\nPackage documentation: REL\n8. Beego ORM #This ORM is part of the Beego web framework. Heavily influenced by Django ORM and SQLAlchemy. It works with PostgreSQL, MySQL, and SQLite databases. The main features are: easy to use CRUD operations, Struct - Table mapping, raw SQL support and query builder, auto joins, transactions support.\nWebsite: https://beego.vip/docs/mvc/model/overview.md\nGithub: https://github.com/beego/beego/tree/master/client/orm\nPackage documentation: Beego ORM\n","date":"24 May 2022","permalink":"https://gosamples.dev/list-postgresql-drivers/","section":"Tutorials","summary":"","title":"🐘 Best PostgreSQL database drivers and ORMs in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/list/","section":"Tags","summary":"","title":"List"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/regex/","section":"Tags","summary":"","title":"Regex"},{"content":"To clear a string from all non-alphanumeric characters in Go, it is best to use a regular expression that matches non-alphanumeric characters, and replace them with an empty string. Such a regex is defined as the negation of the set of allowed characters. For the English alphabet, it would be:\n[^a-zA-Z0-9 ]+\nIn this regular expression, we use the Caret character after a square bracket [^, which means that it matches any character other than a lowercase and uppercase letter in the range a-z, a number, and a space character. \u0026ldquo;Not a letter, not a number, not a space\u0026rdquo; is our definition of a non-alphanumeric character.\nHowever, when working with alphabets other than English, such a regular expression will not work properly. In that case, we can use the Unicode categories in the regex and instead of manually defining the range of letters and numbers, we can use the Unicode category \\p{L} for letters and \\p{N} for numbers:\n[^\\p{L}\\p{N} ]+\nThis regular expression matches any character that is not a Unicode letter and number or a space character.\nTo compare these regular expressions and the results of functions that remove non-alphanumeric characters, see the following two examples.\nRemove all non-alphanumeric characters for English alphabet strings #This is a classic example of removing non-alphanumeric characters from a string. First, we compile our regular expression that matches any character other than an English letter, number, or space. Then, we use the Regexp.ReplaceAllString() method to replace the matched non-alphanumeric characters with the empty string \u0026quot;\u0026quot;. Look at the output and notice that this method removes both non-English letters (ـا, ą) and numbers (٦).\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;regexp\u0026#34; ) var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9 ]+`) func clearString(str string) string { return nonAlphanumericRegex.ReplaceAllString(str, \u0026#34;\u0026#34;) } func main() { str := \u0026#34;Test@%String#321gosamples.dev ـا ą ٦\u0026#34; fmt.Println(clearString(str)) } Output:\nTestString321gosamplesdev Remove all non-alphanumeric characters for non-English alphabet strings #This example works like the previous one, but by using a regular expression with Unicode categories, we also accept letters and numbers from alphabets other than English, such as Arabic.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;regexp\u0026#34; ) var nonAlphanumericRegex = regexp.MustCompile(`[^\\p{L}\\p{N} ]+`) func clearString(str string) string { return nonAlphanumericRegex.ReplaceAllString(str, \u0026#34;\u0026#34;) } func main() { str := \u0026#34;Test@%String#321gosamples.dev ـا ą ٦\u0026#34; fmt.Println(clearString(str)) } Output:\nTestString321gosamplesdev ـا ą ٦ ","date":"19 May 2022","permalink":"https://gosamples.dev/remove-non-alphanumeric/","section":"Tutorials","summary":"","title":"🧽 Remove non-alphanumeric characters from a string in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/math/","section":"Tags","summary":"","title":"Math"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/numbers/","section":"Tags","summary":"","title":"Numbers"},{"content":"Use the Cbrt() function from the math package to find the cube root of a given number in Go.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { fmt.Println(math.Cbrt(8)) } Output:\n2 ","date":"22 April 2022","permalink":"https://gosamples.dev/cube-root/","section":"Tutorials","summary":"","title":"🧊 Cube root in Go"},{"content":"To find the square root of a specified number in Go, use the Sqrt() function from the math package.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { fmt.Println(math.Sqrt(2)) } Output:\n1.4142135623730951 ","date":"22 April 2022","permalink":"https://gosamples.dev/square-root/","section":"Tutorials","summary":"","title":"🟦 Square root in Go"},{"content":"To generate a random string in Go, you need to write a custom function that randomly selects characters from a given charset as many times as the set length of the output and combines them to form a random, fixed-length string.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;math/rand\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;time\u0026#34; ) const charset = \u0026#34;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\u0026#34; func randomString(n int) string { sb := strings.Builder{} sb.Grow(n) for i := 0; i \u0026lt; n; i++ { sb.WriteByte(charset[rand.Intn(len(charset))]) } return sb.String() } func main() { rand.Seed(time.Now().UnixNano()) fmt.Println(randomString(20)) } How it works #The randomString() function #The strings.Builder initialization # 13 14 sb := strings.Builder{} sb.Grow(n) In the first step, we create the strings.Builder structure and grow its capacity to the size of the output string: n. The strings.Builder is used to efficiently concatenate strings, minimizing the number of copies and memory allocations. In our function, it is used to build and store the output random string.\nSee our post on how to concatenate strings in Go.\nRandom character generating loop # 15 16 17 for i := 0; i \u0026lt; n; i++ { sb.WriteByte(charset[rand.Intn(len(charset))]) } In the for loop, we generate the n (size of the output string) random characters and add them to the previously created strings.Builder. Selecting random characters is done by the rand.Intn() function, which returns a random number between 0 and X, where X is the argument of the rand.Intn() function. In our case, charset[rand.Intn(len(charset))] means that we select a random number in the half-open interval [0,len(charset)), and then get a character from the charset string at this random index. Doing this n times and adding to the result gives us a random string of length n.\nIf you want to limit or add new characters to the set from which the random string is made, modify the charset constant.\nReturn the result # 18 return sb.String() By calling the Builder.String() method, we get the accumulated string that we return from the function.\nThe main() function #Seed # 22 rand.Seed(time.Now().UnixNano()) In the first line of the main() function, we set the timestamp of current time time.Now().UnixNano() as the seed of the pseudorandom number generator. Without it, the rand.Intn() function would return the same result every time, and the output string would remain the same between runs of the program. This is because the pseudo-random number generators produce new values by performing some operations on the previous value, and when the initial value (the seed value) stays the same, you get the same output numbers.\nCalling the randomString() function # 24 fmt.Println(randomString(20)) In the last line, we generate a random string of length 20 and print it to the standard output. Run the program several times to see a different string each time:\nXqtscOKPBRGnAXMnzKzq APHQenfBuRrTlMzDShyr dfXgMuGTnfUkLVZQXonw ","date":"21 April 2022","permalink":"https://gosamples.dev/random-string/","section":"Tutorials","summary":"","title":"🎲 Generate a random string in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/random/","section":"Tags","summary":"","title":"Random"},{"content":"To get the maximum and minimum value of various integer types in Go, use the math package constants. For example, to get the minimum value of the int64 type, which is -9223372036854775808, use the math.MinInt64 constant. To get the maximum value of the int64 type, which is 9223372036854775807, use the math.MaxInt64. To check the minimum and maximum values of different int types, see the following example and its output.\nFor unsigned integer types, only the max constant is available because the minimum value of unsigned types is always 0.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { // int fmt.Printf(\u0026#34;int min - max: %d - %d\\n\u0026#34;, math.MinInt, math.MaxInt) // int8 fmt.Printf(\u0026#34;int8 min - max: %d - %d\\n\u0026#34;, math.MinInt8, math.MaxInt8) // int16 fmt.Printf(\u0026#34;int16 min - max: %d - %d\\n\u0026#34;, math.MinInt16, math.MaxInt16) // int32 fmt.Printf(\u0026#34;int32 min - max: %d - %d\\n\u0026#34;, math.MinInt32, math.MaxInt32) // int64 fmt.Printf(\u0026#34;int64 min - max: %d - %d\\n\u0026#34;, math.MinInt64, math.MaxInt64) // unsigned // uint fmt.Printf(\u0026#34;uint min - max: %d - %d\\n\u0026#34;, uint(0), uint(math.MaxUint)) // uint8 fmt.Printf(\u0026#34;uint8 min - max: %d - %d\\n\u0026#34;, 0, math.MaxUint8) // uint16 fmt.Printf(\u0026#34;uint16 min - max: %d - %d\\n\u0026#34;, 0, math.MaxUint16) // uint32 fmt.Printf(\u0026#34;uint32 min - max: %d - %d\\n\u0026#34;, 0, math.MaxUint32) // uint64 fmt.Printf(\u0026#34;uint64 min - max: %d - %d\\n\u0026#34;, 0, uint64(math.MaxUint64)) } Output:\nint min - max: -9223372036854775808 - 9223372036854775807 int8 min - max: -128 - 127 int16 min - max: -32768 - 32767 int32 min - max: -2147483648 - 2147483647 int64 min - max: -9223372036854775808 - 9223372036854775807 uint min - max: 0 - 18446744073709551615 uint8 min - max: 0 - 255 uint16 min - max: 0 - 65535 uint32 min - max: 0 - 4294967295 uint64 min - max: 0 - 18446744073709551615 ","date":"14 April 2022","permalink":"https://gosamples.dev/int-min-max/","section":"Tutorials","summary":"","title":"🍰 The maximum and minimum value of the int types in Go"},{"content":"The maximum value of the float64 type in Go is 1.79769313486231570814527423731704356798070e+308 and you can get this value using the math.MaxFloat64 constant.\nThe minimum value above zero (smallest positive, non-zero value) of the float64 type in Go is 4.9406564584124654417656879286822137236505980e-324 and you can get this value using the math.SmallestNonzeroFloat64 constant.\nThe maximum value of the float32 type in Go is 3.40282346638528859811704183484516925440e+38 and you can get this value using the math.MaxFloat32 constant.\nThe minimum value above zero (smallest positive, non-zero value) of the float32 type in Go is 1.401298464324817070923729583289916131280e-45 and you can get this value using the math.SmallestNonzeroFloat32 constant.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { fmt.Printf(\u0026#34;min float64: %.50e\\n\u0026#34;, math.SmallestNonzeroFloat64) fmt.Printf(\u0026#34;max float64: %.50e\\n\u0026#34;, math.MaxFloat64) fmt.Printf(\u0026#34;min float32: %.50e\\n\u0026#34;, math.SmallestNonzeroFloat32) fmt.Printf(\u0026#34;max float32: %.50e\\n\u0026#34;, math.MaxFloat32) } Output:\nmin float64: 4.94065645841246544176568792868221372365059802614325e-324 max float64: 1.79769313486231570814527423731704356798070567525845e+308 min float32: 1.40129846432481707092372958328991613128026194187652e-45 max float32: 3.40282346638528859811704183484516925440000000000000e+38 ","date":"14 April 2022","permalink":"https://gosamples.dev/float64-min-max/","section":"Tutorials","summary":"","title":"📊 The maximum and minimum value of the float types in Go"},{"content":"To get the value of the Pi (π) constant in Go, use the mathematical constant math.Pi from the standard library math package.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { fmt.Printf(\u0026#34;%.48f\u0026#34;, math.Pi) } Output:\n3.141592653589793115997963468544185161590576171875 ","date":"13 April 2022","permalink":"https://gosamples.dev/math-pi/","section":"Tutorials","summary":"","title":"🍩 Get Pi constant in Go"},{"content":"To calculate the time difference between two dates, e.g., years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds between one date and the other, use the Sub() method on the time.Time struct. It calculates the difference between the two dates. Then using the built-in methods, you can determine the specific number of hours, minutes, seconds, etc., that have passed in that difference.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func main() { firstDate := time.Date(2022, 4, 13, 1, 0, 0, 0, time.UTC) secondDate := time.Date(2021, 2, 12, 5, 0, 0, 0, time.UTC) difference := firstDate.Sub(secondDate) fmt.Printf(\u0026#34;Years: %d\\n\u0026#34;, int64(difference.Hours()/24/365)) fmt.Printf(\u0026#34;Months: %d\\n\u0026#34;, int64(difference.Hours()/24/30)) fmt.Printf(\u0026#34;Weeks: %d\\n\u0026#34;, int64(difference.Hours()/24/7)) fmt.Printf(\u0026#34;Days: %d\\n\u0026#34;, int64(difference.Hours()/24)) fmt.Printf(\u0026#34;Hours: %.f\\n\u0026#34;, difference.Hours()) fmt.Printf(\u0026#34;Minutes: %.f\\n\u0026#34;, difference.Minutes()) fmt.Printf(\u0026#34;Seconds: %.f\\n\u0026#34;, difference.Seconds()) fmt.Printf(\u0026#34;Milliseconds: %d\\n\u0026#34;, difference.Milliseconds()) fmt.Printf(\u0026#34;Microseconds: %d\\n\u0026#34;, difference.Microseconds()) fmt.Printf(\u0026#34;Nanoseconds: %d\\n\u0026#34;, difference.Nanoseconds()) } There are no built-in methods for calculating the number of days, weeks, months, or years between two dates. You have to do it manually using the Duration.Hours() method.\nOutput:\nYears: 1 Months: 14 Weeks: 60 Days: 424 Hours: 10196 Minutes: 611760 Seconds: 36705600 Milliseconds: 36705600000 Microseconds: 36705600000000 Nanoseconds: 36705600000000000 ","date":"13 April 2022","permalink":"https://gosamples.dev/difference-between-dates/","section":"Tutorials","summary":"","title":"⏳ Time difference between two dates in Go"},{"content":"To get a hostname or domain from a URL in Go, first, use the url.Parse() function, which parses the URL given as input, and then use the url.Hostname() method, which returns the hostname. If you do not want the www. prefix in your domain name, remove it with the strings.TrimPrefix() function.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/url\u0026#34; \u0026#34;strings\u0026#34; ) func main() { input := \u0026#34;https://www.gosamples.dev/abc/def\u0026#34; url, err := url.Parse(input) if err != nil { log.Fatal(err) } hostname := strings.TrimPrefix(url.Hostname(), \u0026#34;www.\u0026#34;) fmt.Println(hostname) } Output:\ngosamples.dev ","date":"12 April 2022","permalink":"https://gosamples.dev/get-hostname-domain/","section":"Tutorials","summary":"","title":"👀 Get a hostname (domain) from a URL in Go"},{"content":"To find the median of a slice in Go, you need to write a custom function that sorts the input slice and gets the middle element. If the slice size is even, the function calculates the mean (average) of the two middle values. In the following examples, we will show two versions of this function: a regular one that takes a float64 slice as input, and a Generics version, that can work for any numeric type.\nIf you are not already familiar with the basics of Generics in Go, check out our series of articles: Introduction to Go Generics by example.\nAlso, check out our tutorial on how to calculate the arithmetic mean in Go.\nCalculate median in Go - example #To calculate the median in the classic way, we need to create a new median() function and start with the input data copy. Calculating the median requires sorting the data first, so to avoid modifying the original slice order, we need a copy of the input slice. We then take the middle value from this sorted slice. This is our median. If the data size is an odd number, the middle element will be the value at index \u0026lt;slice_length\u0026gt;/2. If the data size is even, it will be the arithmetic average of the two middle elements.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;sort\u0026#34; ) func median(data []float64) float64 { dataCopy := make([]float64, len(data)) copy(dataCopy, data) sort.Float64s(dataCopy) var median float64 l := len(dataCopy) if l == 0 { return 0 } else if l%2 == 0 { median = (dataCopy[l/2-1] + dataCopy[l/2]) / 2 } else { median = dataCopy[l/2] } return median } func main() { fmt.Println(median([]float64{1, 3, 2})) fmt.Println(median([]float64{1})) fmt.Println(median([]float64{3, 3, 3, 3, 2, 22, 2, 2, 2, 2, 1, 1, 1, 1, 1, 111})) } Output:\n2 1 2 Use Generics to calculate median #Since the release of Generics in Go 1.18, it is possible to write the median() function that works for a slice of any numeric type. Simply define the Number constraint which is a union of constraints.Float and constraints.Integer to limit the input types to numeric. For more details, see the example on how to calculate the arithmetic mean using Generics, where we also used the Number constraint.\nAnother difference is that, in the generic version, we use the slices.Sort() function from the new /x/exp/slices package to sort the slice. It allows for generic sorting of slices of any type.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/exp/constraints\u0026#34; \u0026#34;golang.org/x/exp/slices\u0026#34; ) type Number interface { constraints.Float | constraints.Integer } func median[T Number](data []T) float64 { dataCopy := make([]T, len(data)) copy(dataCopy, data) slices.Sort(dataCopy) var median float64 l := len(dataCopy) if l == 0 { return 0 } else if l%2 == 0 { median = float64((dataCopy[l/2-1] + dataCopy[l/2]) / 2.0) } else { median = float64(dataCopy[l/2]) } return median } func main() { fmt.Println(median([]float64{1, 3, 2})) fmt.Println(median([]int{1})) fmt.Println(median([]int32{3, 3, 3, 3, 2, 22, 2, 2, 2, 2, 1, 1, 1, 1, 1, 111})) } The result is a function that works seamlessly for a slice of type int, int64, float64, etc., without having to copy code, or create special versions for each type.\nOutput:\n2 1 2 ","date":"11 April 2022","permalink":"https://gosamples.dev/calculate-median/","section":"Tutorials","summary":"","title":"🖖 Calculate Median in Go using Generics"},{"content":"To raise a number X to the power of Y in Go, use the Pow(x, y float64) function from the math package.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { res := math.Pow(2, 7) // 2^7 fmt.Println(res) } Output:\n128 To calculate the power of 10 up to the Y exponent in Go, use the math.Pow10(n int) function.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { res := math.Pow10(3) // 10^3 fmt.Println(res) } Output:\n1000 ","date":"8 April 2022","permalink":"https://gosamples.dev/calculate-power/","section":"Tutorials","summary":"","title":"🏋️‍♂️ Calculate the power of a number x^y in Go"},{"content":"To calculate the arithmetic mean (average value) in Go, you should write your own function that takes a slice of numbers as an input, sum all values in the slice, and divides the sum by the number of elements.\npackage main import \u0026#34;fmt\u0026#34; func mean(data []float64) float64 { if len(data) == 0 { return 0 } var sum float64 for _, d := range data { sum += d } return sum / float64(len(data)) } func main() { fmt.Println(mean([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) } This function requires that the input slice to be of a certain type, such as float64. In case you want to calculate the mean for a slice of, for example, int values, until recently you had to write a separate function that differed only in that it accepted an int slice as an argument. Another solution was to convert the slice to float64 before the calculation. However, the new version of Go 1.18, which introduced Generics, allows you to simplify this problem. All you need to do is write a generic mean() function that takes a slice of any numeric type.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/exp/constraints\u0026#34; ) type Number interface { constraints.Float | constraints.Integer } func mean[T Number](data []T) float64 { if len(data) == 0 { return 0 } var sum float64 for _, d := range data { sum += float64(d) } return sum / float64(len(data)) } func main() { fmt.Println(mean([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) fmt.Println(mean([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) } If you are not already familiar with the basics of Generics in Go, check out our series of articles: Introduction to Go Generics by example.\nCheck also our example on how to calculate median in Go.\nIn the example above, we start with the custom constraint declaration. The Number interface is a type set being union of constraints.Float and constraints.Integer.\nThis is a new feature released along with Generics in Go 1.18 - now interfaces can have not only a set of methods but also a set of types. Just use the | operator to declare the set of types that our generic function should accept. In our case, we accept constraints.Float and constraints.Integer types, which are themselves type sets containing all floating and integer point types.\nThe rest of the new mean() function is the same as in the non-generic version. The only difference is that we use type T instead of float64 for the input data. The function result is still float64, because no matter if the input is a slice of integers or floating-point numbers, we can get a floating-point number as the result of the mean.\n","date":"8 April 2022","permalink":"https://gosamples.dev/calculate-mean/","section":"Tutorials","summary":"","title":"🤏 Calculate arithmetic mean in Go using Generics"},{"content":"When working with external files or user input, it is often a good idea to remove invisible characters that can cause problems. These characters are \u0026ldquo;non-printable\u0026rdquo; - they do not occupy a space in printing and fall under the Other or Separator category in the Unicode standard. For example, non-printable are:\nWhitespaces (except the ASCII space character) Tabs Line breaks Carriage returns Control characters To remove non-printable characters from a string in Go, you should iterate over the string and check if a given rune is printable using the unicode.IsPrint() function. If not, the rune should be ignored, otherwise it should be added to the new string.\nInstead of iterating and manually creating a new string in the for loop, you can use the strings.Map(), which returns a copy of the string with all characters modified according to the mapping function. The best part is that the character is dropped if the mapping function returns a negative value for a given rune. So, we can return -1 for a non-printable character, and an unmodified rune if the unicode.IsPrint() returns true. See the following example:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;unicode\u0026#34; ) func main() { text := \u0026#34;b\\u00a0e\\u200bhind\\n\u0026#34; fmt.Println(text) fmt.Println(len(text)) fmt.Println(\u0026#34;---\u0026#34;) text = strings.Map(func(r rune) rune { if unicode.IsPrint(r) { return r } return -1 }, text) fmt.Println(text) fmt.Println(len(text)) } Output\nb e​hind 12 --- behind 6 The unicode.IsPrint() returns true for:\nletters marks numbers punctuation symbols the ASCII space character There is also a function unicode.IsGraphic(), that works almost the same, except that it returns true for all space characters in the category Zs of the Unicode standard.\n","date":"6 April 2022","permalink":"https://gosamples.dev/remove-non-printable-characters/","section":"Tutorials","summary":"","title":"🚧 Remove non-printable characters from a string in Go"},{"content":"To create a new empty file in Go, use the os.Create() function.\nIt creates a new file if it does not exist, with the file mode 0666, for reading and writing. It truncates the file if it exists, which means that the contents of the file are removed without deleting the file. The returned file descriptor is open for reading and writing. If there is some problem, the function returns an error of type *os.PathError. package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { f, err := os.Create(\u0026#34;testFile.txt\u0026#34;) if err != nil { log.Fatal(err) } defer f.Close() fmt.Println(f.Name()) } Always remember to close the open file descriptor when you finish working with the file so that the system can reuse it:\ndefer f.Close() You can then write data to this file. See how to do this in one of our previous tutorials here.\n","date":"5 April 2022","permalink":"https://gosamples.dev/create-file/","section":"Tutorials","summary":"","title":"🐤 Create a new file in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/file/","section":"Tags","summary":"","title":"File"},{"content":"To delete/remove a file in Go, use the built-in os.Remove() function:\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { if err := os.Remove(\u0026#34;testfile.txt\u0026#34;); err != nil { log.Fatal(err) } } If the file exists, the function removes the file without any error. If there is some problem, it returns an error of type *os.PathError. For example, if the file does not exist, the error is:\n2022/04/05 06:16:05 remove testfile.txt: no such file or directory exit status 1 ","date":"5 April 2022","permalink":"https://gosamples.dev/delete-remove-file/","section":"Tutorials","summary":"","title":"🧹 Delete or remove a file in Go"},{"content":"In short, the ternary operator known from languages like PHP or JavaScript is not available in Go. But you can express the same condition using the if {..} else {..} block, which is longer but easier to understand. The fact that it is not in the syntax is the result of a deliberate choice by the language designers, who noticed that the ternary operator is often used to create overly complicated expressions.\nAs a result, there is only one conditional control flow construct in Go: if {..} else {..}. So, instead of writing:\n// this is not available in Go! variable := \u0026lt;condition\u0026gt; ? \u0026lt;expressionIfTrue\u0026gt; : \u0026lt;expressionIfFalse\u0026gt; you need to write:\nvar variable int if \u0026lt;condition\u0026gt; { variable = \u0026lt;expressionIfTrue\u0026gt; } else { variable = \u0026lt;expressionIfFalse\u0026gt; } Example:\nx := 12 var points int if x \u0026gt; 10 { points = 100 } else { points = 0 } fmt.Println(points) Output:\n100 ","date":"1 April 2022","permalink":"https://gosamples.dev/ternary-operator/","section":"Tutorials","summary":"","title":"🦥 Ternary operator in Go"},{"content":"To print or create a string with double quotes in Go, you can use any of the following methods:\nFormat a string using %q verb in the fmt.Printf() or fmt.Sprintf() functions. Format a string using escaped double quotes \\\u0026quot; in the fmt.Printf() or fmt.Sprintf() functions. Use the strconv.Quote() function. Format a double-quoted string using a raw string literal - a string between back quotes ` in the fmt.Printf() or fmt.Sprintf() functions. See the examples below to learn how each of these methods works.\nPrint a string with double quotes using the %q format verb #The easiest method of creating of printing string with double quotes is to use the fmt.Printf() or fmt.Sprintf() functions with the %q format verb, which is designed to do just that. From the fmt package documentation:\n%q\ta double-quoted string safely escaped with Go syntax\nExample:\npackage main import \u0026#34;fmt\u0026#34; func main() { str := \u0026#34;Hello https://gosamples.dev\u0026#34; // print string with double quotes fmt.Printf(\u0026#34;%q\\n\u0026#34;, str) // create string with double quotes quoted := fmt.Sprintf(\u0026#34;%q\u0026#34;, str) fmt.Println(quoted) } Print a string with double quotes using the format with escaped double quotes #Alternatively, to print or create a string with double quotes, you can add these quotes manually in the format of the fmt.Printf() or fmt.Sprintf() functions. Note that the quotes within the string must be escaped by adding a backslash character before the quotation mark: \\\u0026quot;.\nExample:\npackage main import \u0026#34;fmt\u0026#34; func main() { str := \u0026#34;Hello https://gosamples.dev\u0026#34; // print string with double quotes fmt.Printf(\u0026#34;\\\u0026#34;%s\\\u0026#34;\\n\u0026#34;, str) // create string with double quotes quoted := fmt.Sprintf(\u0026#34;\\\u0026#34;%s\\\u0026#34;\u0026#34;, str) fmt.Println(quoted) } Create a string with double quotes using the strconv.Quote() function #It is also possible to use the function strconv.Quote() to create a new string with double quotes. In this case, printing and creating look almost the same because you need to create the quoted string first, and then you can print or use it in the application.\nExample:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strconv\u0026#34; ) func main() { str := \u0026#34;Hello https://gosamples.dev\u0026#34; // print string with double quotes fmt.Println(strconv.Quote(str)) // create string with double quotes quoted := strconv.Quote(str) fmt.Println(quoted) } Print a string with double quotes using back quotes (raw string) format #The last, most human-friendly method for creating or printing string with double quotes is to use the raw string literal in the format of the fmt.Printf() or fmt.Sprintf() functions. The raw string literal is any character sequence between back quotes, such as `abc`. Strings between back quotes are printed as they are, they may contain newlines, and escape characters are not interpreted.\nSo in our case, we do not have to use the escaped double-quote character as in the second example. The only problem is when we want to print the quoted string with the newline at the end. Look at the example below. Since we are printing the raw string, we have to use Enter to add a newline character which makes the code look ugly. For this reason, we recommend using the second method rather, with the double quotes escaped.\nExample:\npackage main import \u0026#34;fmt\u0026#34; func main() { str := \u0026#34;Hello https://gosamples.dev\u0026#34; // print string with double quotes fmt.Printf(`\u0026#34;%s\u0026#34; `, str) // create string with double quotes quoted := fmt.Sprintf(`\u0026#34;%s\u0026#34;`, str) fmt.Println(quoted) } All of the examples return the same output 😉:\n\u0026#34;Hello https://gosamples.dev\u0026#34; \u0026#34;Hello https://gosamples.dev\u0026#34; ","date":"31 March 2022","permalink":"https://gosamples.dev/string-double-quotes/","section":"Tutorials","summary":"","title":"✌️ 4 ways to create or print string with double quotes in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/slice/","section":"Tags","summary":"","title":"Slice"},{"content":"In one of our previous examples, we created a function that removes duplicate values from a slice in Go. This function, however, needs to be reimplemented each time the slice is of a different type. So, if we had []int and []string slices that we wanted to remove duplicates from, so far, we needed two functions: uniqueString() and uniqueInt(). But with the release of the Generics in Go 1.18, this is no longer necessary. We can write a single function that will work on any slice where the values satisfy the comparable constraint.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package main import \u0026#34;fmt\u0026#34; func unique[T comparable](s []T) []T { inResult := make(map[T]bool) var result []T for _, str := range s { if _, ok := inResult[str]; !ok { inResult[str] = true result = append(result, str) } } return result } type FruitRank struct { Fruit string Rank uint64 } func main() { fmt.Println(unique([]string{\u0026#34;abc\u0026#34;, \u0026#34;cde\u0026#34;, \u0026#34;efg\u0026#34;, \u0026#34;efg\u0026#34;, \u0026#34;abc\u0026#34;, \u0026#34;cde\u0026#34;})) fmt.Println(unique([]int{1, 1, 2, 2, 3, 3, 4})) fruits := []FruitRank{ { Fruit: \u0026#34;Strawberry\u0026#34;, Rank: 1, }, { Fruit: \u0026#34;Raspberry\u0026#34;, Rank: 2, }, { Fruit: \u0026#34;Blueberry\u0026#34;, Rank: 3, }, { Fruit: \u0026#34;Blueberry\u0026#34;, Rank: 3, }, { Fruit: \u0026#34;Strawberry\u0026#34;, Rank: 1, }, } fmt.Println(unique(fruits)) } Output:\n[abc cde efg] [1 2 3 4] [{Strawberry 1} {Raspberry 2} {Blueberry 3}] If you are not already familiar with the basics of Generics in Go, check out our series of articles: Introduction to Go Generics by example.\nThe function differs from the non-generic version only in that it uses a type parameter T with the comparable constraint. This is a built-in constraint that describes any type on which the == and != operators can be used.\nThe unique() function that we created is a universal duplicate removal function that, as you can see in the output of the example, works on any comparable slice such as []string, []int, or a defined struct slice.\n","date":"30 March 2022","permalink":"https://gosamples.dev/generics-remove-duplicates-slice/","section":"Tutorials","summary":"","title":"🗑️ Remove duplicates from any slice using Generics in Go"},{"content":"To read user input from the terminal console in Go, you can use several methods:\nfmt.Scanln(), fmt.Scan(), fmt.Scanf() functions which allow you to read successive words into separate variables. bufio.Reader struct which can read a line of the input text or a single character. bufio.Scanner which provides a convenient interface for reading lines of text. As usual, which method to use depends on the use case. In the next sections, we will show how to read a single or multiple lines of the user input from the console, how to read a single character, how to read data from formatted input, and finally, how to read numbers from the terminal.\nRead a single line from standard input # Use fmt.Scanln() to read a single line of text #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) var w1, w2, w3 string n, err := fmt.Scanln(\u0026amp;w1, \u0026amp;w2, \u0026amp;w3) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;number of items read: %d\\n\u0026#34;, n) fmt.Printf(\u0026#34;read line: %s %s %s-\\n\u0026#34;, w1, w2, w3) } Output:\ninput text: ab cd ef number of items read: 3 read line: ab cd ef- Use bufio.Reader to read a single line of text #package main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) reader := bufio.NewReader(os.Stdin) line, err := reader.ReadString(\u0026#39;\\n\u0026#39;) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;read line: %s-\\n\u0026#34;, line) } Output:\ninput text: ab cd ef read line: ab cd ef - Use bufio.Scanner to read a single line of text #package main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) scanner := bufio.NewScanner(os.Stdin) scanner.Scan() err := scanner.Err() if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;read line: %s-\\n\u0026#34;, scanner.Text()) } Output:\ninput text: ab cd ef number of items read: 3 read line: ab cd ef- Use the fmt.Scanln() function if you want to read each word of a line into a different variable, and there is a certain number of words to read, no less, no more. Use the bufio.Reader if you want to read a full line of text together with the newline character. Use the bufio.Scanner to read a full line of text in a convenient way without the newline character. Read multiple lines from console # Use fmt.Scan() to read multiple lines of text #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) var w1, w2, w3 string n, err := fmt.Scan(\u0026amp;w1, \u0026amp;w2, \u0026amp;w3) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;number of items read: %d\\n\u0026#34;, n) fmt.Printf(\u0026#34;read text: %s %s %s-\\n\u0026#34;, w1, w2, w3) } Output:\ninput text: ab cd ef number of items read: 3 read text: ab cd ef- With the fmt.Scan() you can read multiple lines of text only if the line consists of a single word.\nUse bufio.Reader to read multiple lines of text #package main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;strings\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) reader := bufio.NewReader(os.Stdin) var lines []string for { line, err := reader.ReadString(\u0026#39;\\n\u0026#39;) if err != nil { log.Fatal(err) } if len(strings.TrimSpace(line)) == 0 { break } lines = append(lines, line) } fmt.Println(\u0026#34;output:\u0026#34;) for _, l := range lines { fmt.Println(l) } } Output:\ninput text: ab cd ef gh hj kl mn op output: ab cd ef gh hj kl mn op Use bufio.Scanner to read multiple lines of text #package main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) scanner := bufio.NewScanner(os.Stdin) var lines []string for { scanner.Scan() line := scanner.Text() if len(line) == 0 { break } lines = append(lines, line) } err := scanner.Err() if err != nil { log.Fatal(err) } fmt.Println(\u0026#34;output:\u0026#34;) for _, l := range lines { fmt.Println(l) } } Output:\ninput text: ab cd ef gh hj kl mn op output: ab cd ef gh hj kl mn op Use the fmt.Scan() if you want to read multiple words where each word is on a separate line. Use the bufio.Reader if you want to read multiple lines together with the newline character at the end of each line. The most recommended and universal method of reading multiple lines is to use the bufio.Scanner, which allows you to get a list of input lines without the newline character at the end of each line. Read a single character from terminal # Use bufio.Reader to read a single character #package main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) reader := bufio.NewReader(os.Stdin) char, _, err := reader.ReadRune() if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;read character: %c-\\n\u0026#34;, char) } Output:\ninput text: abfd read character: a- Use fmt.Scanf() to read a single character #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) var char rune _, err := fmt.Scanf(\u0026#34;%c\u0026#34;, \u0026amp;char) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;read character: %c-\\n\u0026#34;, char) } Output:\ninput text: abcd read character: a- Reading a single character is possible via the bufio.Reader and its ReadRune() method, which returns the rune, the size of the rune, and the reading error. A slightly simpler, single-line method for reading a character is to use the fmt.Scanf() function with the %c. Read formatted user input #When you want to accept text only of a specific format and read certain items into variables, the best method is to use the fmt.Scanf() function, which reads the text according to a given format.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { fmt.Println(\u0026#34;input text:\u0026#34;) var name string var country string n, err := fmt.Scanf(\u0026#34;%s is born in %s\u0026#34;, \u0026amp;name, \u0026amp;country) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;number of items read: %d\\n\u0026#34;, n) fmt.Println(name, country) } input text: Anna is born in Germany number of items read: 2 Anna Germany Read numbers from user input #Reading numbers from the terminal console can be done by using the fmt.Scanf() or fmt.Scan() functions. The first one requires an input format - for numbers, it is %d for integers or %f for floating-point numbers. The second, which is simpler, does not require a format but discovers itself how the input data should be parsed to match the output variable.\nUse fmt.Scanf() to read a number #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { fmt.Println(\u0026#34;input number:\u0026#34;) var number int64 _, err := fmt.Scanf(\u0026#34;%d\u0026#34;, \u0026amp;number) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;read number: %d\\n\u0026#34;, number) } Output:\ninput number: 8 read number: 8 Use fmt.Scan() to read a number #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { fmt.Println(\u0026#34;input number:\u0026#34;) var number int64 _, err := fmt.Scan(\u0026amp;number) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;read number: %d\\n\u0026#34;, number) } Output:\ninput number: 8 read number: 8 ","date":"28 March 2022","permalink":"https://gosamples.dev/read-user-input/","section":"Tutorials","summary":"","title":"⌨️ Read user input in Go [cheatsheet]"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/input/","section":"Tags","summary":"","title":"Input"},{"content":" Format date #To format a date in Go, use the time.Format() method of the Time struct:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func main() { t := time.Now() fmt.Println(t.Format(time.RFC3339)) } Parse date #To parse a date in Go, use the time.Parse() function from the time package:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) // date time format layout const YYYYMMDD = \u0026#34;2006-01-02\u0026#34; func main() { s := \u0026#34;2022-03-23\u0026#34; t, err := time.Parse(YYYYMMDD, s) if err != nil { log.Fatal(err) } fmt.Println(t) } Parse date with a timezone #The time.Parse() interprets a time as UTC. To parse a time at a specific location, use the time.ParseInLocation() function:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { s := \u0026#34;2022-03-23T07:00:00+01:00\u0026#34; loc, _ := time.LoadLocation(\u0026#34;Europe/Berlin\u0026#34;) t, err := time.ParseInLocation(time.RFC3339, s, loc) if err != nil { log.Fatal(err) } fmt.Println(t) } Reference layout #To format or parse a date, you need to specify the layout of the input or output date string. The Go language uses a specific date layout format in which each part of the date has an ordinal index:\n\u0026quot;01/02 03:04:05PM '06 -0700\u0026quot;\n01 - month 02 - day 03 - hour (12h) 04 - minute 05 - second 06 - year 07 - time zone offset Useful date and time layouts #Some layouts, not defined in the time package, which are useful in everyday coding:\nconst ( // YYYY-MM-DD: 2022-03-23 YYYYMMDD = \u0026#34;2006-01-02\u0026#34; // 24h hh:mm:ss: 14:23:20 HHMMSS24h = \u0026#34;15:04:05\u0026#34; // 12h hh:mm:ss: 2:23:20 PM HHMMSS12h = \u0026#34;3:04:05 PM\u0026#34; // text date: March 23, 2022 TextDate = \u0026#34;January 2, 2006\u0026#34; // text date with weekday: Wednesday, March 23, 2022 TextDateWithWeekday = \u0026#34;Monday, January 2, 2006\u0026#34; // abbreviated text date: Mar 23 Wed AbbrTextDate = \u0026#34;Jan 2 Mon\u0026#34; ) Predefined layouts #The built-in time/date layouts defined in the time package:\nconst ( Layout = \u0026#34;01/02 03:04:05PM \u0026#39;06 -0700\u0026#34; // The reference time, in numerical order. ANSIC = \u0026#34;Mon Jan _2 15:04:05 2006\u0026#34; UnixDate = \u0026#34;Mon Jan _2 15:04:05 MST 2006\u0026#34; RubyDate = \u0026#34;Mon Jan 02 15:04:05 -0700 2006\u0026#34; RFC822 = \u0026#34;02 Jan 06 15:04 MST\u0026#34; RFC822Z = \u0026#34;02 Jan 06 15:04 -0700\u0026#34; // RFC822 with numeric zone RFC850 = \u0026#34;Monday, 02-Jan-06 15:04:05 MST\u0026#34; RFC1123 = \u0026#34;Mon, 02 Jan 2006 15:04:05 MST\u0026#34; RFC1123Z = \u0026#34;Mon, 02 Jan 2006 15:04:05 -0700\u0026#34; // RFC1123 with numeric zone RFC3339 = \u0026#34;2006-01-02T15:04:05Z07:00\u0026#34; RFC3339Nano = \u0026#34;2006-01-02T15:04:05.999999999Z07:00\u0026#34; Kitchen = \u0026#34;3:04PM\u0026#34; // Handy time stamps. Stamp = \u0026#34;Jan _2 15:04:05\u0026#34; StampMilli = \u0026#34;Jan _2 15:04:05.000\u0026#34; StampMicro = \u0026#34;Jan _2 15:04:05.000000\u0026#34; StampNano = \u0026#34;Jan _2 15:04:05.000000000\u0026#34; ) All date formatting strings #Date format # Year format Go layout Format Example Description 2006 YYYY \"2022\" Four-digit year 06 YY \"22\" Two-digit year Month format Go layout Format Example Description January MMMM \"July\" Full month name Jan MMM \"Jul\" Three-letter abbreviation of the month 01 MM \"07\" Two-digit month (with a leading 0 if necessary) 1 M \"7\" At most two-digit month (without a leading 0) Day format Go layout Format Example Description Monday DDDD \"Tuesday\" Full weekday name Mon DDD \"Tue\" Three-letter abbreviation of the weekday 02 DD \"08\" Two-digit month day (with a leading 0 if necessary) _2 _D \" 8\" Two-character month day with a leading space if necessary 2 D \"8\" At most two-digit month day (without a leading 0) 002 ddd \"074\" Three-digit day of the year (with a leading 0 if necessary) __2 __d \" 74\" Three-character day of the year with a leading spaces if necessary Time format # Hour format Go layout Format Example Description 15 hh \"17\" Two-digit 24h format hour 03 hh \"05\" Two digit 12h format hour (with a leading 0 if necessary) 3 h \"5\" At most two-digit 12h format hour (without a leading 0) PM am/pm \"AM\" AM/PM mark (uppercase) pm am/pm \"am\" AM/PM mark (lowercase) Minute format Go layout Format Example Description 04 mm \"07\" Two-digit minute (with a leading 0 if necessary) 4 m \"7\" At most two-digit minute (without a leading 0) Second format Go layout Format Example Description 05 ss \"09\" Two-digit second (with a leading 0 if necessary) 5 s \"9\" At most two-digit second (without a leading 0) .0, .00, \u0026hellip;, .000000000 .s \".126284000\" A fractional second (trailing zeros included) .9, .99, \u0026hellip;, .999999999 .s \".126284\" A fractional second (trailing zeros omitted) Time zone format # Time zone format Go layout Format Example Description MST TTT \"CEST\" Abbreviation of the time zone -070000 ±hhmmss \"+010000\" Numeric time zone offset with hours, minutes, and seconds -07:00:00 ±hh:mm:ss \"+01:00:00\" Numeric time zone offset with hours, minutes, and seconds separated by colons -0700 ±hhmm \"+0100\" Numeric time zone offset with hours and minutes -07:00 ±hh:mm \"+01:00\" Numeric time zone offset with hours and minutes separated by colons -07 ±hh \"+01\" Numeric time zone offset with hours Z070000 Z or ±hhmmss \"+010000\" Like -070000 but prints \"Z\" instead of \"+000000\" for the UTC zone (ISO 8601 behavior) Z07:00:00 Z or ±hh:mm:ss \"+01:00:00\" Like -07:00:00 but prints \"Z\" instead of \"+00:00:00\" for the UTC zone (ISO 8601 behavior) Z0700 Z or ±hhmm \"+0100\" Like -0700 but prints \"Z\" instead of \"+0000\" for the UTC zone (ISO 8601 behavior) Z07:00 Z or ±hh:mm \"+01:00\" Like -07:00 but prints \"Z\" instead of \"+00:00\" for the UTC zone (ISO 8601 behavior) Z07 Z or ±hh \"+01\" Like -07 but prints \"Z\" instead of \"+00\" for the UTC zone (ISO 8601 behavior) ","date":"23 March 2022","permalink":"https://gosamples.dev/date-time-format-cheatsheet/","section":"Tutorials","summary":"","title":"🕰️ Date and time format in Go cheatsheet"},{"content":"The reduce() function is a functional programming concept popularized by other programming languages such as JavaScript and Python. It works by reducing an array to a single value by applying a function generating a partial result to each element of the array. The result after the last item is the cumulative value from the entire list. So far in Go, it has not been easy to create this type of function that would work for different types. However, with the Go 1.18 release, which introduces Generics, this is no longer a problem.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package main import ( \u0026#34;fmt\u0026#34; ) func reduce[T, M any](s []T, f func(M, T) M, initValue M) M { acc := initValue for _, v := range s { acc = f(acc, v) } return acc } func main() { numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sum := reduce(numbers, func(acc, current int) int { return acc + current }, 0) fmt.Println(sum) divided := reduce(numbers, func(acc float64, current int) float64 { return acc + float64(current)/10.0 }, 0) fmt.Println(divided) } Output:\n55 5.5 Let\u0026rsquo;s look at the example. The reduce() function takes as parameters:\nA slice of any type T An initial value of any type M which is a start value of our accumulator - the value that accumulates partial results of reducer function calls. Note that the accumulator type need not be the same as the slice type. A reducer function that takes the accumulator and current value of the slice and returns the new accumulator. As a result, we created a function that works similarly to the reduce() known from other languages. In the first example of the main(), it is used to sum a slice of numbers, and in the second, to sum the same slice, where each value is divided by 10 and the result is float64 rather than int.\n","date":"16 March 2022","permalink":"https://gosamples.dev/generics-reduce/","section":"Tutorials","summary":"","title":"🔉 Reduce function using Generics in Go"},{"content":"The map() function is another functional programming paradigm that can be easily implemented in Go thanks to the new Generics feature. It works by applying a function that takes a single slice element as an argument, transforms it, and returns output value, where the types taken and returned need not be the same. For example, you can use the map() function to convert string to int slice; or format each element of the string slice, without changing the output type. Such different use cases are not problematic when using Generics as the map() can run on any input and output types.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; \u0026#34;strconv\u0026#34; ) func mapSlice[T any, M any](a []T, f func(T) M) []M { n := make([]M, len(a)) for i, e := range a { n[i] = f(e) } return n } func main() { numbers := []float64{4, 9, 16, 25} newNumbers := mapSlice(numbers, math.Sqrt) fmt.Println(newNumbers) words := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;, \u0026#34;d\u0026#34;} quoted := mapSlice(words, func(s string) string { return \u0026#34;\\\u0026#34;\u0026#34; + s + \u0026#34;\\\u0026#34;\u0026#34; }) fmt.Println(quoted) stringPowNumbers := mapSlice(numbers, func(n float64) string { return strconv.FormatFloat(math.Pow(n, 2), \u0026#39;f\u0026#39;, -1, 64) }) fmt.Println(stringPowNumbers) } Output:\n[2 3 4 5] [\u0026#34;a\u0026#34; \u0026#34;b\u0026#34; \u0026#34;c\u0026#34; \u0026#34;d\u0026#34;] [16 81 256 625] The mapSlice() function (we use the name mapSlice() because map is Golang keyword) takes two type parameters. T is the type of the input slice, and M is the type of the output slice. Both of them can be of any type. The function also takes two arguments: the slice a and the function f that transforms each of its elements. Notice that this function converts the value of the input type T into the output type M. The mapSlice() works by creating a new output slice of the same length as the input and transforming each element of the input slice into the output slice in a loop by using the f function. This simple code is enough to get a universal map() function that, as the example shows, can square float64 elements of a slice, format strings by adding quotes, or raise numbers to a power.\n","date":"16 March 2022","permalink":"https://gosamples.dev/generics-map-function/","section":"Tutorials","summary":"","title":"🦾 Create a slice 'map' function using Generics in Go"},{"content":"Until now, it was difficult to create in Go the filter() function known from functional programming, which filters any list of elements according to the boolean value of the predicate. It was possible if you knew the type of the list:\n1 2 3 4 5 6 7 8 9 func filter(slice []string, f func(string) bool) []string { var n []string for _, e := range slice { if f(e) { n = append(n, e) } } return n } The main drawback of this solution was that you had to write a separate function for each slice type or use interface{} and type assertions.\nHowever, with the release of Generics in Go 1.18, we got the ability to write functions where type is a parameter. So now there is no problem writing a filter() function that operates on a slice of any type.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func filter[T any](slice []T, f func(T) bool) []T { var n []T for _, e := range slice { if f(e) { n = append(n, e) } } return n } func main() { websites := []string{\u0026#34;http://foo.com\u0026#34;, \u0026#34;https://bar.com\u0026#34;, \u0026#34;https://gosamples.dev\u0026#34;} httpsWebsites := filter(websites, func(v string) bool { return strings.HasPrefix(v, \u0026#34;https://\u0026#34;) }) fmt.Println(httpsWebsites) numbers := []int{1, 2, 3, 4, 5, 6} divisibleBy2 := filter(numbers, func(v int) bool { return v % 2 == 0 }) fmt.Println(divisibleBy2) } Output:\n[https://bar.com https://gosamples.dev] [2 4 6] The filter() function takes as an argument a slice of type T. The T type has the any constraint, and as you already know from our previous tutorial on Generics, this constraint means that there are no requirements on the type of the slice - it can be anything. The same type T is used as an argument to the predicate function that checks whether the value should be added to the result. The body of the filter() function is simple. It performs an iteration over the slice and adds to the result those elements that return true from the predicate function. As you can see in the output of the example, it works with slices of both string and int types, as well as any other type.\n","date":"16 March 2022","permalink":"https://gosamples.dev/generics-filter/","section":"Tutorials","summary":"","title":"💂 Filter a slice using Generics in Go"},{"content":"Sorting a slice in Go is one of the things that you used to have to re-write every time there was a new slice type. Sometimes you ended up with the same code for two different types. Since Go 1.18, and thanks to the new Generics feature, this is no longer an issue. You can write a single universal sort function that works for any type whose values can be ordered.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\nInstead of writing your own function, you can use sorting functions slices.Sort() and slices.SortFunc() from the golang.org/x/exp/slices package, released together with the Go 1.18.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;sort\u0026#34; \u0026#34;golang.org/x/exp/constraints\u0026#34; ) func sortSlice[T constraints.Ordered](s []T) { sort.Slice(s, func(i, j int) bool { return s[i] \u0026lt; s[j] }) } func main() { floatSlice := []float64{2.3, 1.2, 0.2, 51.2} sortSlice(floatSlice) fmt.Println(floatSlice) stringSlice := []string{\u0026#34;z\u0026#34;, \u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;} sortSlice(stringSlice) fmt.Println(stringSlice) intSlice := []int{0, 3, 2, 1, 6} sortSlice(intSlice) fmt.Println(intSlice) } The only new thing we introduce here compared to our previous tutorial is the new constraints.Ordered constraint in the sortSlice() function. It guarantees that the function can sort values of any type supporting the operators \u0026lt;, \u0026lt;=, \u0026gt;=, \u0026gt;. For proof, see the output of the main() examples, where three different type slices are sorted with a single function:\n[0.2 1.2 2.3 51.2] [a b z] [0 1 2 3 6] Sorting is a very natural use case for the new Generics feature. It makes the code concise and introduces virtually no complexity.\n","date":"16 March 2022","permalink":"https://gosamples.dev/generics-sort-slice/","section":"Tutorials","summary":"","title":"🩰 Sort a slice of any type using Generics in Go"},{"content":"Before Go 1.18, when you wanted to pull a list of keys from a map in Go, you had to write code that iterated over the map and added the keys to a slice. Since then, with the new Generics feature, you can write a single universal function that gets keys from any map and use it whenever you need it. No more writing code for a specific type of map 😉.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\nAlong with the Go 1.18 release, the golang.org/x/exp/maps package has also been released, with the Keys() function working the same as the one below.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package main import ( \u0026#34;fmt\u0026#34; ) func keys[K comparable, V any](m map[K]V) []K { keys := make([]K, 0, len(m)) for k := range m { keys = append(keys, k) } return keys } func main() { vegetableSet := map[string]bool{ \u0026#34;potato\u0026#34;: true, \u0026#34;cabbage\u0026#34;: true, \u0026#34;carrot\u0026#34;: true, } fruitRank := map[int]string{ 1: \u0026#34;strawberry\u0026#34;, 2: \u0026#34;raspberry\u0026#34;, 3: \u0026#34;blueberry\u0026#34;, } fmt.Printf(\u0026#34;vegetableSet keys: %+v\\n\u0026#34;, keys(vegetableSet)) fmt.Printf(\u0026#34;fruitRank keys: %+v\\n\u0026#34;, keys(fruitRank)) } The keys() function takes a map as an argument, in which the keys are of the type with comparable constraint, and the values, with any constraint. As you may already know from our previous tutorial on Generics, the comparable constraint describes types whose values can be compared, meaning that the == and != operators can be used on them. The any constraint is equivalent to interface{} - it accepts any type, so the values of a map can be anything.\nThe rest of the function is very simple. It returns a slice of keys []K, so in the first line of the function body, the resulting slice is created. Notice that it has a capacity equal to the size of the map. Then, in a loop, each map key is added to the resulting slice. Running the example code with two different maps, you get the output:\nvegetableSet keys: [potato cabbage carrot] fruitRank keys: [1 2 3] And that\u0026rsquo;s all. Now, with a single keys() function, you can get a list of keys for any map.\n","date":"16 March 2022","permalink":"https://gosamples.dev/generics-map-keys/","section":"Tutorials","summary":"","title":"🔑 Get a slice of keys from any map using Generics in Go"},{"content":"Checking if an array contains a given value is a popular programming function implemented natively in many programming languages. In Go, we have to implement it ourselves, but thanks to the new Generics feature, we can write a single contains() function that will work for slices of any type whose values can be compared.\nIf you want to see how to write the contains() function without Generics, that only works for string slices, check one of our previous tutorials here.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package main import \u0026#34;fmt\u0026#34; func contains[T comparable](elems []T, v T) bool { for _, s := range elems { if v == s { return true } } return false } func main() { fmt.Println(contains([]string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;}, \u0026#34;b\u0026#34;)) fmt.Println(contains([]int{1, 2, 3}, 2)) fmt.Println(contains([]int{1, 2, 3}, 10)) } Along with the Go 1.18 release, the golang.org/x/exp/slices package has also been released, with the Contains() function working the same as the one above.\nAs you already know from our previous Generics tutorial, the type parameters of the generic functions are declared in square brackets after the function name. In the contains(), we use the T type parameter with the comparable constraint. It is a built-in constraint that describes any type whose values can be compared, i.e., we can use == and != operators on them. The function body is really simple and does not differ from the non-generic version. We iterate over the elems slice and check if the current value is the value v we are looking for. This way, we get a function that can operate on any slice type.\nOutput of the main() function:\ntrue true false ","date":"16 March 2022","permalink":"https://gosamples.dev/generics-slice-contains/","section":"Tutorials","summary":"","title":"🔍 'Slice contains' function using Generics in Go"},{"content":"Getting the minimum and maximum from a slice are some of the simplest functions that are written by developers during everyday coding. The problem is that when you wanted to get the minimum or maximum from int and float64 slices, up until now, you had to write two functions for each slice type. However, since version 1.18, Go has introduced the much-anticipated Generics, and you can now write single min() and max() functions that work for any ordered type.\nThis article is part of the Introduction to Go Generics series. Go here to see more.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/exp/constraints\u0026#34; ) func max[T constraints.Ordered](s []T) T { if len(s) == 0 { var zero T return zero } m := s[0] for _, v := range s { if m \u0026lt; v { m = v } } return m } func min[T constraints.Ordered](s []T) T { if len(s) == 0 { var zero T return zero } m := s[0] for _, v := range s { if m \u0026gt; v { m = v } } return m } func main() { fmt.Println(min([]int{10, 2, 4, 1, 6, 8, 2})) fmt.Println(max([]float64{3.2, 5.1, 6.2, 7.6, 8.2, 1.5, 4.8})) } Generic functions need type parameters that describe types that are allowed for a given function and provide the type label used in the function body. As you can see in the example, they are declared in square brackets after the name of a function:\nfunc name[TypeLabel Constraints](...) { ... } In the min() and max() functions we declare a type parameter T with constraints.Ordered constraint. It guarantees that the functions work only for slice types that support the operators \u0026lt;, \u0026lt;=, \u0026gt;=, \u0026gt;. The rest of the functions are pretty straightforward. They take a slice of type T as an argument, return a zero value for a given type if the slice has size 0, and find the minimum or maximum of the slice in a loop. As a result, they return a single min or max value of type T.\nFrom the example above, we get the following output:\n1 8.2 It is really exciting how, thanks to Generics, it is possible to make things that were not possible before in Go. We are sure that this feature will improve the code quality of any Go project 😊.\n","date":"16 March 2022","permalink":"https://gosamples.dev/generics-min-max/","section":"Tutorials","summary":"","title":"☯️ Min and max functions using Generics in Go"},{"content":"To format date in Go as YYYY-MM-DD, use the time.Format() function with the layout: \u0026quot;2006-01-02\u0026quot;. To format date as DD/MM/YYYY, use the \u0026quot;02/01/2006\u0026quot; layout. To format date as YYYY-MM-DD hh:mm:ss, use the \u0026quot;2006-01-02 15:04:05\u0026quot; layout.\nExamples # If you are not familiar with the Go date formatting layouts, read the documentation in the time package.\nSee also the cheatsheet on date and time format in Go.\nYYYY-MM-DD date format in Go #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) const ( YYYYMMDD = \u0026#34;2006-01-02\u0026#34; ) func main() { now := time.Now().UTC() fmt.Println(now.Format(YYYYMMDD)) } Output:\n2022-03-14 DD/MM/YYYY date format in Go #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) const ( DDMMYYYY = \u0026#34;02/01/2006\u0026#34; ) func main() { now := time.Now().UTC() fmt.Println(now.Format(DDMMYYYY)) } Output:\n14/03/2022 YYYY-MM-DD hh:mm:ss date format in Go #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) const ( DDMMYYYYhhmmss = \u0026#34;2006-01-02 15:04:05\u0026#34; ) func main() { now := time.Now().UTC() fmt.Println(now.Format(DDMMYYYYhhmmss)) } Output:\n2022-03-14 05:41:33 ","date":"14 March 2022","permalink":"https://gosamples.dev/date-format-yyyy-mm-dd/","section":"Tutorials","summary":"","title":"📅 YYYY-MM-DD date format in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/errors/","section":"Tags","summary":"","title":"Errors"},{"content":"Wrapping errors in Go means adding extra context information to the returned error like the name of the function where the error occurred, the cause, the type, etc. This technique is most commonly used to create clear error messages, which are especially useful for debugging when you want quickly and precisely locate the source of problems.\nTo wrap an error in Go, you need to create a new error using the fmt.Errorf(format string, a \\.\\.\\.interface{}) error function with the verb %w in the format:\nvar ErrorCritical = errors.New(\u0026#34;critical error\u0026#34;) ... wrapped := fmt.Errorf(\u0026#34;[functionName] internal error: %w\u0026#34;, ErrorCritical) The resulting error is a chain, in which the wrapped error can be \u0026lsquo;unwrapped\u0026rsquo; using the errors.Unwrap() function:\nfmt.Println(errors.Unwrap(wrapped) == ErrorCritical) // true It is also possible to check if a given error exists anywhere in the chain thanks to the errors.Is() and errors.As() functions. See the examples below for details on how to wrap, unwrap, and test for error types.\nCheck out more examples of error handling in Go using the errors.Is() and errors.As() functions in our other tutorial.\nExamples #In the first example, we create the getError() function that returns a non-wrap, single-wrap, or double-wrap error depending on the parameter set. The error we wrap is a simple built-in error instance.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; ) var ( ErrorInternal = errors.New(\u0026#34;internal error\u0026#34;) ) func getError(level int) error { level1Err := fmt.Errorf(\u0026#34;[getData] level 1 error: %w\u0026#34;, ErrorInternal) if level == 1 { return level1Err } if level == 2 { return fmt.Errorf(\u0026#34;[getData] level 2 error: %w\u0026#34;, level1Err) } return ErrorInternal } func main() { err := getError(1) if errors.Is(err, ErrorInternal) { fmt.Printf(\u0026#34;is error internal: %v\\n\u0026#34;, err) } fmt.Printf(\u0026#34;unwrapped error: %v\\n\u0026#34;, errors.Unwrap(err)) fmt.Printf(\u0026#34;---\\n\u0026#34;) err = getError(2) if errors.Is(err, ErrorInternal) { fmt.Printf(\u0026#34;is error internal: %v\\n\u0026#34;, err) } unwrapped := errors.Unwrap(err) fmt.Printf(\u0026#34;unwrapped error: %v\\n\u0026#34;, unwrapped) fmt.Printf(\u0026#34;unwrapped unwrapped error: %v\\n\u0026#34;, errors.Unwrap(unwrapped)) } Output:\nis error internal: [getData] level 1 error: internal error unwrapped error: internal error --- is error internal: [getData] level 2 error: [getData] level 1 error: internal error unwrapped error: [getData] level 1 error: internal error unwrapped unwrapped error: internal error Let\u0026rsquo;s go through the main() function and the output. In lines 25-29, we get a single-wrap error and test if it is an ErrorInternal error. As you can see, the errors.Is() function returns true because it checks if any error in the chain matches the target. It does not matter that the error is wrapped. A simple comparison if err == ErrorInternal would give false in this case, so it is generally a better idea to use the errors.Is() function to compare errors equality. Then, we unwrap the error using the errors.Unwrap() and print it to the standard output. Unwrapping the error gives the ErrorInternal that we wrapped before.\nIn lines 33-39, we get a double-wrap error. The errors.Is() returns that the ErrorInternal is in the chain, even though it is double-wrapped. As you might expect, a double unwrapping is needed to get to the ErrorInternal.\nSimilarly, you can wrap, unwrap and test for errors of a specific type. Look at the second example below. The result is analogous to the first example with a simple error instance. The only difference is the use of the errors.As() function instead of errors.Is(), which checks if the error in the chain is of the specific type.\nMore examples of error handling using the errors.Is() and errors.As() can be found here.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; ) type ErrorInternal struct { function string } func (e *ErrorInternal) Error() string { return fmt.Sprintf(\u0026#34;[%s] error internal\u0026#34;, e.function) } func getError(level int) error { level1Err := fmt.Errorf(\u0026#34;level 1 error: %w\u0026#34;, \u0026amp;ErrorInternal{function: \u0026#34;getData\u0026#34;}) if level == 1 { return level1Err } if level == 2 { return fmt.Errorf(\u0026#34;level 2 error: %w\u0026#34;, level1Err) } return \u0026amp;ErrorInternal{function: \u0026#34;getData\u0026#34;} } func main() { err := getError(1) var internalErr *ErrorInternal if errors.As(err, \u0026amp;internalErr) { fmt.Printf(\u0026#34;is error internal: %v\\n\u0026#34;, err) } fmt.Printf(\u0026#34;unwrapped error: %v\\n\u0026#34;, errors.Unwrap(err)) fmt.Printf(\u0026#34;---\\n\u0026#34;) err = getError(2) if errors.As(err, \u0026amp;internalErr) { fmt.Printf(\u0026#34;is error internal: %v\\n\u0026#34;, err) } unwrapped := errors.Unwrap(err) fmt.Printf(\u0026#34;unwrapped error: %v\\n\u0026#34;, unwrapped) fmt.Printf(\u0026#34;unwrapped unwrapped error: %v\\n\u0026#34;, errors.Unwrap(unwrapped)) } Output:\nis error internal: level 1 error: [getData] error internal unwrapped error: [getData] error internal --- is error internal: level 2 error: level 1 error: [getData] error internal unwrapped error: level 1 error: [getData] error internal unwrapped unwrapped error: [getData] error internal ","date":"13 March 2022","permalink":"https://gosamples.dev/wrap-unwrap-errors/","section":"Tutorials","summary":"","title":"🌯 Wrap and Unwrap errors in Go"},{"content":"To round a floating-point number in Go, you can use the math.Round() function from the built-in math package. However, this function rounds to the nearest integer, so it cannot be used directly to round a float to a particular precision. But you can use it to create your own function that rounds to any decimal places. All you need to do is:\nmultiply the number to be rounded times 10 to the power of X, where X is the precision you want to achieve round this raised number to the nearest integer value using the math.Round() function divide the rounded number by 10 to the power of X, where X is the rounding decimal precision In this way, by rounding the raised number to the nearest integer and then dividing, we get a number rounded to the specified decimal places.\nExamples #The roundFloat() is a floating-point rounding function, working as described above. The way it works is shown in the example:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func roundFloat(val float64, precision uint) float64 { ratio := math.Pow(10, float64(precision)) return math.Round(val*ratio) / ratio } func main() { number := 12.3456789 fmt.Println(roundFloat(number, 2)) fmt.Println(roundFloat(number, 3)) fmt.Println(roundFloat(number, 4)) fmt.Println(roundFloat(number, 5)) number = -12.3456789 fmt.Println(roundFloat(number, 0)) fmt.Println(roundFloat(number, 1)) fmt.Println(roundFloat(number, 10)) } Output:\n12.35 12.346 12.3457 12.34568 -12 -12.3 -12.3456789 Round float to 2 decimal places #Full example of rounding a float to 2 decimal places:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func roundFloat(val float64, precision uint) float64 { ratio := math.Pow(10, float64(precision)) return math.Round(val*ratio) / ratio } func main() { number := 12.3456789 fmt.Println(roundFloat(number, 2)) } Output:\n12.35 Round float to 3 decimal places #Full example of rounding a float to 3 decimal places:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func roundFloat(val float64, precision uint) float64 { ratio := math.Pow(10, float64(precision)) return math.Round(val*ratio) / ratio } func main() { number := 12.3456789 fmt.Println(roundFloat(number, 3)) } Output:\n12.346 Round the float to a string #In Go, there is another way of rounding numbers often called float truncation. The difference from classical rounding is that you get the result in the form of a string, as truncating is carried out by the formatting function fmt.Sprintf() or fmt.Printf(). To round a float in this way, you must set the formatting verb %f as an argument to these functions with a precision value of %.nf where n specifies the precision, that is, the number of decimal places.\nThe example below is equivalent to the first example on rounding, except it uses the fmt.Printf() function.\npackage main import ( \u0026#34;fmt\u0026#34; ) func main() { number := 12.3456789 fmt.Printf(\u0026#34;%.2f\\n\u0026#34;, number) fmt.Printf(\u0026#34;%.3f\\n\u0026#34;, number) fmt.Printf(\u0026#34;%.4f\\n\u0026#34;, number) fmt.Printf(\u0026#34;%.5f\\n\u0026#34;, number) number = -12.3456789 fmt.Printf(\u0026#34;%.0f\\n\u0026#34;, number) fmt.Printf(\u0026#34;%.1f\\n\u0026#34;, number) fmt.Printf(\u0026#34;%.10f\\n\u0026#34;, number) } Output:\n12.35 12.346 12.3457 12.34568 -12 -12.3 -12.3456789000 As you can see, the results are similar to using our roundFloat() function. The difference is when we set a higher precision in the fmt.Printf() than the number itself has - then the trailing zeros are displayed in the resulting string:\nFor:\nfmt.Printf(\u0026#34;%.10f\\n\u0026#34;, number) you get:\n-12.3456789000 Below is the same example, but it formats the results into a string type variable:\npackage main import ( \u0026#34;fmt\u0026#34; ) func main() { number := 12.3456789 numberString := fmt.Sprintf(\u0026#34;%.2f\u0026#34;, number) fmt.Println(numberString) numberString = fmt.Sprintf(\u0026#34;%.3f\u0026#34;, number) fmt.Println(numberString) numberString = fmt.Sprintf(\u0026#34;%.4f\u0026#34;, number) fmt.Println(numberString) numberString = fmt.Sprintf(\u0026#34;%.5f\u0026#34;, number) fmt.Println(numberString) number = -12.3456789 numberString = fmt.Sprintf(\u0026#34;%.0f\u0026#34;, number) fmt.Println(numberString) numberString = fmt.Sprintf(\u0026#34;%.1f\u0026#34;, number) fmt.Println(numberString) numberString = fmt.Sprintf(\u0026#34;%.10f\u0026#34;, number) fmt.Println(numberString) } ","date":"10 March 2022","permalink":"https://gosamples.dev/round-float/","section":"Tutorials","summary":"","title":"🎠 Round float to any precision in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/map/","section":"Tags","summary":"","title":"Map"},{"content":"To check if a given key exists in a map in Go, use the special form of the index expression v, ok := a[k] which returns two elements - a value v of the map with the key k, and a boolean value ok equal to true if the key k is present in the map. If not, the ok is false.\nExample #data := map[string]int{ \u0026#34;a\u0026#34;: 1, \u0026#34;b\u0026#34;: 2, \u0026#34;c\u0026#34;: 3, } val, ok := data[\u0026#34;a\u0026#34;] fmt.Println(val, ok) val, ok = data[\u0026#34;d\u0026#34;] fmt.Println(val, ok) Output:\n1 true 0 false How to check if a key exists in a map directly in an if statement #In everyday coding, a common situation is that you only want to execute a certain piece of code if a given key exists in the map. In Go, you can do this by combining the if statement with the map index expression.\nif val, ok := data[\u0026#34;a\u0026#34;]; ok { fmt.Println(val, ok) } if val, ok := data[\u0026#34;d\u0026#34;]; ok { fmt.Println(val, ok) } Output:\n1 true If statements can be preceded by simple statements that allow you to assign map values directly in the if, before evaluating it.\nWhy is checking for zero values not sufficient? #You may be wondering why we cannot use the simpler map index expression which returns a single value and check if it is not the zero value:\nif data[\u0026#34;a\u0026#34;] != 0 { fmt.Println(\u0026#34;key a exists\u0026#34;) } Output:\nkey a exists It works fine if you are sure that your map does not contain zero values. Otherwise, the result will be incorrect:\n// incorrect result data[\u0026#34;d\u0026#34;] = 0 if data[\u0026#34;d\u0026#34;] != 0 { fmt.Println(\u0026#34;key d exists\u0026#34;) } else { fmt.Println(\u0026#34;key d does not exist\u0026#34;) } Output:\nkey d does not exist For this reason, it is a better idea to use a two-values map index expression for checking whether a map contains a given key in Go.\n","date":"8 March 2022","permalink":"https://gosamples.dev/map-contains-key/","section":"Tutorials","summary":"","title":"🗝️ Check if a map contains a key in Go"},{"content":"To print a number with thousands separator in Go, you can use the Printer object from the official golang.org/x/text/message package. Its job is to translate text strings from one language to another, and it also allows you to print numbers in a language-specific format.\nMore specifically, the message.Printer object allows a number to be formatted using the Unicode CLDR.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/text/language\u0026#34; \u0026#34;golang.org/x/text/message\u0026#34; ) func main() { number := 1_000_000.23456 p := message.NewPrinter(language.English) withCommaThousandSep := p.Sprintf(\u0026#34;%f\u0026#34;, number) fmt.Println(withCommaThousandSep) } Output:\n1,000,000.234560 In standard English format, the comma is the thousands separator, and the point is the decimal separator. However, you can format the number in any language format:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;golang.org/x/text/language\u0026#34; \u0026#34;golang.org/x/text/message\u0026#34; ) func main() { number := 1_000_000.23456 langs := []language.Tag{ language.German, language.Ukrainian, language.Chinese, language.Arabic, language.French, } for _, l := range langs { p := message.NewPrinter(l) withCommaThousandSep := p.Sprintf(\u0026#34;%s %f\u0026#34;, l, number) fmt.Println(withCommaThousandSep) } } Output:\nde 1.000.000,234560 uk 1 000 000,234560 zh 1,000,000.234560 ar ١٬٠٠٠٬٠٠٠٫٢٣٤٥٦٠ fr 1 000 000,234560 ","date":"7 March 2022","permalink":"https://gosamples.dev/print-number-thousands-separator/","section":"Tutorials","summary":"","title":"📒 Print a number with (comma) thousands separator in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/format/","section":"Tags","summary":"","title":"Format"},{"content":"When writing an HTTP server or client in Go, it is often useful to print the full HTTP request or response to the standard output for debugging purposes. Using fmt.Println() may not be sufficient in this case because the output is not formatted and difficult to read. The better idea is to use the httputil.DumpRequest(), httputil.DumpRequestOut() and httputil.DumpResponse() functions which were created to pretty-print the HTTP request and response. Such pretty-printing or dumping means that the request/response is presented in a similar format as it is sent to and received from the server.\nThe rules for using these functions are simple:\nUse httputil.DumpRequest() if you want to pretty-print the request on the server side. Use httputil.DumpRequestOut() if you want to dump the request on the client side. Use httputil.DumpResponse() if you want to log the server response. The second argument in each of these functions: body bool is a flag indicating if the body of the request/response should also be returned. Log client requests and responses #Check the example below to learn how to dump the HTTP client request and response using the httputil.DumpRequestOut() and httputil.DumpResponse() functions.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;net/http/httputil\u0026#34; ) const serverAddr = \u0026#34;http://example.com/\u0026#34; func main() { req, err := http.NewRequest(http.MethodGet, serverAddr, nil) if err != nil { log.Fatal(err) } req.Header.Add(\u0026#34;test-header\u0026#34;, \u0026#34;test-header-value\u0026#34;) reqDump, err := httputil.DumpRequestOut(req, true) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;REQUEST:\\n%s\u0026#34;, string(reqDump)) resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } respDump, err := httputil.DumpResponse(resp, true) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;RESPONSE:\\n%s\u0026#34;, string(respDump)) } Output:\nREQUEST: GET / HTTP/1.1 Host: example.com User-Agent: Go-http-client/1.1 Test-Header: test-header-value Accept-Encoding: gzip RESPONSE: HTTP/1.1 200 OK Accept-Ranges: bytes Age: 357425 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Fri, 25 Feb 2022 06:48:03 GMT Etag: \u0026#34;3147526947+gzip\u0026#34; Expires: Fri, 04 Mar 2022 06:48:03 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECS (bsa/EB18) Vary: Accept-Encoding X-Cache: HIT \u0026lt;!doctype html\u0026gt; \u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;Example Domain\u0026lt;/title\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; \u0026lt;meta http-equiv=\u0026#34;Content-type\u0026#34; content=\u0026#34;text/html; charset=utf-8\u0026#34; /\u0026gt; \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1\u0026#34; /\u0026gt; \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; ... Log requests on the server side #From the example below, you can find out how to pretty-print an incoming server request using the httputil.DumpRequest() function.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;net/http/httputil\u0026#34; ) const port = 8080 func indexHandler(w http.ResponseWriter, r *http.Request) { reqDump, err := httputil.DumpRequest(r, true) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;REQUEST:\\n%s\u0026#34;, string(reqDump)) w.Write([]byte(\u0026#34;Hello World\u0026#34;)) } func main() { http.HandleFunc(\u0026#34;/\u0026#34;, indexHandler) log.Printf(\u0026#34;Starting HTTP server at port: %d\\n\u0026#34;, port) log.Fatal(http.ListenAndServe(fmt.Sprintf(\u0026#34;:%d\u0026#34;, port), nil)) } Output:\n2022/02/25 07:03:20 Starting HTTP server at port: 8080 REQUEST: GET / HTTP/1.1 Host: localhost:8080 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,en-US;q=0.8,en;q=0.7 Connection: keep-alive Dnt: 1 Sec-Ch-Ua: \u0026#34; Not A;Brand\u0026#34;;v=\u0026#34;99\u0026#34;, \u0026#34;Chromium\u0026#34;;v=\u0026#34;98\u0026#34;, \u0026#34;Google Chrome\u0026#34;;v=\u0026#34;98\u0026#34; Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: \u0026#34;macOS\u0026#34; Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 REQUEST: GET /favicon.ico HTTP/1.1 Host: localhost:8080 Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,en-US;q=0.8,en;q=0.7 Connection: keep-alive Dnt: 1 Referer: http://localhost:8080/ Sec-Ch-Ua: \u0026#34; Not A;Brand\u0026#34;;v=\u0026#34;99\u0026#34;, \u0026#34;Chromium\u0026#34;;v=\u0026#34;98\u0026#34;, \u0026#34;Google Chrome\u0026#34;;v=\u0026#34;98\u0026#34; Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: \u0026#34;macOS\u0026#34; Sec-Fetch-Dest: image Sec-Fetch-Mode: no-cors Sec-Fetch-Site: same-origin User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 ","date":"28 February 2022","permalink":"https://gosamples.dev/print-http-request-response/","section":"Tutorials","summary":"","title":"🐜 Print HTTP request/response for debugging in Go"},{"content":"The do-while is a popular programming loop found in many languages such as C++, Java, or JavaScript. It is similar to the while loop but with the difference that the body of the do-while is executed at least once. In Go, there is no special expression to create the do-while loop, but we can easily simulate it using a for loop. We just need to ensure that it executes at least once.\nThe classic for has the form of:\nfor \u0026lt;initialization\u0026gt;; \u0026lt;condition\u0026gt;; \u0026lt;post-condition\u0026gt; { \u0026lt;loopBody\u0026gt; } To ensure that it executes at least once, the \u0026lt;condition\u0026gt; must be true for the first iteration and be dependent on the loop stop condition in subsequent iterations:\nfor next := true; next; next=\u0026lt;condition\u0026gt; { \u0026lt;loopBody\u0026gt; } There is also a simpler form of the do-while loop in Go, in which the \u0026lt;condition\u0026gt; of the for loop is checked after the \u0026lt;loopBody\u0026gt; and if it is not true the loop is exited:\nfor { \u0026lt;loopBody\u0026gt; if !\u0026lt;condition\u0026gt; { break } } Examples #The first version of the do-while loop: #Print the i variable if the value is less than 5:\ni := 0 for next := true; next; next = i \u0026lt; 5 { fmt.Println(i) i++ } Output:\n0 1 2 3 4 Check that the loop is executed at least once:\ni := 10 for next := true; next; next = i \u0026lt; 5 { fmt.Println(i) i++ } Output:\n10 The second version of the do-while loop: #Print the i variable if the value is less than 5:\ni := 0 for { fmt.Println(i) i++ if i \u0026gt;= 5 { break } } Output:\n0 1 2 3 4 This version of the loop is also executed at least once 😉:\ni := 10 for { fmt.Println(i) i++ if i \u0026gt;= 5 { break } } Output:\n10 ","date":"22 February 2022","permalink":"https://gosamples.dev/do-while/","section":"Tutorials","summary":"","title":"🐉 Do-while loop in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/loop/","section":"Tags","summary":"","title":"Loop"},{"content":"Maps in Go are reference types, so to deep copy the contents of a map, you cannot assign one instance to another. You can do this by creating a new, empty map and then iterating over the old map in a for range loop to assign the appropriate key-value pairs to the new map. It is the simplest and most efficient solution to this problem in Go.\npackage main import \u0026#34;fmt\u0026#34; func main() { fruitRank := map[string]int{ \u0026#34;strawberry\u0026#34;: 1, \u0026#34;blueberry\u0026#34;: 2, \u0026#34;raspberry\u0026#34;: 3, } // copy a map fruitRankCopy := make(map[string]int) for k, v := range fruitRank { fruitRankCopy[k] = v } fruitRankCopy[\u0026#34;apple\u0026#34;] = 4 fmt.Println(\u0026#34;original map\u0026#34;) fmt.Println(fruitRank) fmt.Println(\u0026#34;copied map\u0026#34;) fmt.Println(fruitRankCopy) } Output:\noriginal map map[blueberry:2 raspberry:3 strawberry:1] copied map map[apple:4 blueberry:2 raspberry:3 strawberry:1] As you see in the output, the copied map is a deep clone, and adding new elements does not affect the old map.\nBe careful when making a shallow copy by assigning one map to another. In this case, a modification in either map will cause a change in the data of both maps.\npackage main import \u0026#34;fmt\u0026#34; func main() { fruitRank := map[string]int{ \u0026#34;strawberry\u0026#34;: 1, \u0026#34;blueberry\u0026#34;: 2, \u0026#34;raspberry\u0026#34;: 3, } fruitRankShallowCopy := fruitRank fruitRankShallowCopy[\u0026#34;apple\u0026#34;] = 4 fmt.Println(\u0026#34;original map\u0026#34;) fmt.Println(fruitRank) fmt.Println(\u0026#34;copied map\u0026#34;) fmt.Println(fruitRankShallowCopy) } Output:\noriginal map map[apple:4 blueberry:2 raspberry:3 strawberry:1] copied map map[apple:4 blueberry:2 raspberry:3 strawberry:1] ","date":"16 February 2022","permalink":"https://gosamples.dev/copy-map/","section":"Tutorials","summary":"","title":"💕 Copy a map in Go"},{"content":"In Go, if you have a slice of simple type like []int, []string, or []float64, you can sort the slice using the sort.Ints(), sort.Strings(), or sort.Float64s() functions. However, they only sort a slice in ascending order. To sort in descending order, you must use the more general function sort.Sort() with the data reversal function sort.Reverse().\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;sort\u0026#34; ) func main() { numbers := []int{4, 3, 2, 1, 0, 4, 7, 5} // sort ints ascending sort.Ints(numbers) fmt.Println(numbers) // sort ints descending sort.Sort(sort.Reverse(sort.IntSlice(numbers))) fmt.Println(numbers) // sort strings descending chars := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} sort.Sort(sort.Reverse(sort.StringSlice(chars))) fmt.Println(chars) } Output:\n[0 1 2 3 4 4 5 7] [7 5 4 4 3 2 1 0] [c b a] Look at the example. To sort a []int slice in descending order you need to:\nConvert the []int slice to sort.IntSlice, which makes the slice an instance of the sort.Interface interface. Reverse the standard ascending order of the elements included in the sort.IntSlice by using the sort.Reverse() function. Sort the reversed slice using the general sort.Sort() function. The same scheme applies when sorting a []string or []float64 list, but it must be converted to sort.StringSlice or sort.Float64Slice.\nThere is no built-in option to reverse the order when using the sort.Slice() with a custom sorting function less. However, we can do it ourselves. In the example below, the reverse() function \u0026ldquo;reverses\u0026rdquo; the less function. This way, we can create a single less function for sorting a slice of structs and then sort it in ascending or descending order depending on a parameter or use case.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;sort\u0026#34; ) type Fruit struct { Name string Color string Rank int } func reverse(less func(i, j int) bool) func(i, j int) bool { return func(i, j int) bool { return !less(i, j) } } func main() { fruits := []Fruit{ { Name: \u0026#34;Strawberry\u0026#34;, Color: \u0026#34;red\u0026#34;, Rank: 2, }, { Name: \u0026#34;Raspberry\u0026#34;, Color: \u0026#34;pink\u0026#34;, Rank: 1, }, { Name: \u0026#34;Banana\u0026#34;, Color: \u0026#34;yellow\u0026#34;, Rank: 3, }, } less := func(i, j int) bool { return fruits[i].Rank \u0026lt; fruits[j].Rank } // sort structs ascending sort.Slice(fruits, less) fmt.Println(fruits) // sort structs descending sort.Slice(fruits, reverse(less)) fmt.Println(fruits) } Output:\n[{Raspberry pink 1} {Strawberry red 2} {Banana yellow 3}] [{Banana yellow 3} {Strawberry red 2} {Raspberry pink 1}] ","date":"11 February 2022","permalink":"https://gosamples.dev/sort-slice-reverse/","section":"Tutorials","summary":"","title":"◀️ Reverse sort a slice in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/sort/","section":"Tags","summary":"","title":"Sort"},{"content":"If you want to remove duplicate values from a slice in Go, you need to create a function that:\nIterates over the slice. Checks if a given value of the slice is in the set of the result values. If not, it adds the value to the resulting slice. If so, it skips the value (we already have it in the output slice). Returns new output slice with duplicates removed. The most important part of the unique() function is to create a set of seen values, which is a map of type map[string]bool, so it can check if the element is already in the resulting slice.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package main import \u0026#34;fmt\u0026#34; func unique(s []string) []string { inResult := make(map[string]bool) var result []string for _, str := range s { if _, ok := inResult[str]; !ok { inResult[str] = true result = append(result, str) } } return result } func main() { fmt.Println(unique([]string{\u0026#34;abc\u0026#34;, \u0026#34;cde\u0026#34;, \u0026#34;efg\u0026#34;, \u0026#34;efg\u0026#34;, \u0026#34;abc\u0026#34;, \u0026#34;cde\u0026#34;})) } Output:\n[abc cde efg] As an output, you get a new slice with all values unique. The function works in the same way for slices of different types. You just need to replace all occurrences of type string with another selected type.\nWith the release of Generics in Go 1.18, you can write a universal function to remove duplicates without having to re-implement it every time a slice is of a different type. Check out how to do it here.\n","date":"4 February 2022","permalink":"https://gosamples.dev/remove-duplicates-slice/","section":"Tutorials","summary":"","title":"✂️ Remove duplicates from a slice in Go"},{"content":"There are situations when you want to limit the number of bytes read, e.g., from a server response or a file. In such a case, you can count bytes during reading and stop the process at the right moment. However, there are simpler methods in Go. Using the io.LimitedReader wrapper, you can read the set number of bytes from the underlying reader without modifying the reading code, as it creates a new io.Reader limited to a fixed number of N bytes.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;io/ioutil\u0026#34; \u0026#34;log\u0026#34; \u0026#34;strings\u0026#34; ) func main() { r := strings.NewReader(\u0026#34;https://gosamples.dev\u0026#34;) limitedReader := \u0026amp;io.LimitedReader{R: r, N: 8} body, err := ioutil.ReadAll(limitedReader) if err != nil { log.Fatal(err) } fmt.Println(string(body)) } Output:\nhttps:// Look at the example. In the main() function, we initialize a simple strings.Reader that contains an URL, and we want to read the first 8 bytes from it. To do this, we create a new io.LimitedReader in line 14 that takes the underlying io.Reader and the number of bytes to read as arguments. As a result, when reading data from this stream, we will not get more than the set number of N bytes.\n","date":"26 January 2022","permalink":"https://gosamples.dev/io-limited-reader/","section":"Tutorials","summary":"","title":"✋ Limit read bytes using io.LimitedReader in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/io/","section":"Tags","summary":"","title":"Io"},{"content":"To define an infinite loop in Go, also known as a \u0026ldquo;while true\u0026rdquo; loop in many different languages, you need to use the for statement. The traditional for loop has the form of:\nfor initialization; condition; post-condition { ... } but when you omit the initialization, condition, and post-condition statements, you get the classic \u0026ldquo;while true\u0026rdquo; infinite loop:\nfor { ... } There is no while keyword in Go, so all \u0026ldquo;while\u0026rdquo; loops can be created with the for keyword.\nExample:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func main() { for { fmt.Println(\u0026#34;https://gosamples.dev is the best\u0026#34;) time.Sleep(1 * time.Second) } } ","date":"2 December 2021","permalink":"https://gosamples.dev/infinite-loop/","section":"Tutorials","summary":"","title":"♾️ Infinite loop in Go"},{"content":"To convert a struct to io.Reader in Go and send it as an HTTP POST request body, you need to encode the object to byte representation, for example, JSON. The result of the encoding should be stored in the bytes.Buffer or bytes.Reader objects which implement the io.Reader interface.\nCheck how to convert a byte slice to io.Reader\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package main import ( \u0026#34;bytes\u0026#34; \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; ) type Fruit struct { Name string `json:\u0026#34;name\u0026#34;` Color string `json:\u0026#34;color\u0026#34;` } func main() { // encode a Fruit object to JSON and write it to a buffer f := Fruit{ Name: \u0026#34;Apple\u0026#34;, Color: \u0026#34;green\u0026#34;, } var buf bytes.Buffer err := json.NewEncoder(\u0026amp;buf).Encode(f) if err != nil { log.Fatal(err) } client := \u0026amp;http.Client{} req, err := http.NewRequest(http.MethodPost, \u0026#34;https://postman-echo.com/post\u0026#34;, \u0026amp;buf) if err != nil { log.Fatal(err) } resp, err := client.Do(req) if err != nil { log.Fatal(err) } bytes, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(bytes)) } In lines 19-27, we create a new instance of the Fruit struct and encode it into JSON using json.Encoder. The result is written to a bytes.Buffer, which implements the io.Writer and io.Reader interfaces. In this way, we can use this buffer not only as an io.Writer, to which the JSON result is stored, but also as io.Reader, required when making a POST request.\nAlternatively, you can encode the struct into a JSON byte slice using the json.Marshal() function and create a new bytes.Reader that is a struct for reading data from this slice which implements the required io.Reader interface.\n19 20 21 22 23 24 25 26 27 28 29 30 f := Fruit{ Name: \u0026#34;Apple\u0026#34;, Color: \u0026#34;green\u0026#34;, } data, err := json.Marshal(f) if err != nil { log.Fatal(err) } reader := bytes.NewReader(data) client := \u0026amp;http.Client{} req, err := http.NewRequest(http.MethodPost, \u0026#34;https://postman-echo.com/post\u0026#34;, reader) ","date":"1 December 2021","permalink":"https://gosamples.dev/struct-to-io-reader/","section":"Tutorials","summary":"","title":"📔 Convert a struct to io.Reader in Go"},{"content":"When you send an HTTP request to a server, you often want to read the contents of the response. In Go, the body of the response can be found in the Response.Body field of the http.Response object, which is returned as the result of sending a request by an HTTP client. The HTTP response body in Go is of type io.ReadCloser. To convert the io.ReadCloser object to a string, you need to read the contents of this field using the io.ReadAll() function.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; ) func main() { client := \u0026amp;http.Client{} req, err := http.NewRequest(http.MethodGet, \u0026#34;https://example.com/\u0026#34;, nil) if err != nil { log.Fatal(err) } resp, err := client.Do(req) if err != nil { log.Fatal(err) } bytes, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(bytes)) } In the example above, we are making a standard GET request to the https://example.com/ website. On line 21, we read the response body with the io.ReadAll() function. This function returns the read response body as a slice of bytes, so in order to print it, we need to convert it to a string.\nAs the output of the example, you will see the HTML content of the https://example.com/ website:\n\u0026lt;!doctype html\u0026gt; \u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;Example Domain\u0026lt;/title\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; \u0026lt;meta http-equiv=\u0026#34;Content-type\u0026#34; content=\u0026#34;text/html; charset=utf-8\u0026#34; /\u0026gt; \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1\u0026#34; /\u0026gt; \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, \u0026#34;Segoe UI\u0026#34;, \u0026#34;Open Sans\u0026#34;, \u0026#34;Helvetica Neue\u0026#34;, Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;div\u0026gt; \u0026lt;h1\u0026gt;Example Domain\u0026lt;/h1\u0026gt; \u0026lt;p\u0026gt;This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.\u0026lt;/p\u0026gt; \u0026lt;p\u0026gt;\u0026lt;a href=\u0026#34;https://www.iana.org/domains/example\u0026#34;\u0026gt;More information...\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; ","date":"29 November 2021","permalink":"https://gosamples.dev/io-readcloser-to-string/","section":"Tutorials","summary":"","title":"📟 Convert HTTP response io.ReadCloser to string in Go"},{"content":"To duplicate a slice in Go, getting a deep copy of its contents, you need to either use the built-in copy() function, or create a new empty slice and add all the elements of the first slice to it using the append() function. Because of how slices are built in Go, assigning one slice to another only makes a shallow copy, and you should not use it if you want to clone the slice in a deep way.\nCopy a slice using the copy() function #package main import \u0026#34;fmt\u0026#34; func main() { src := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} dst := make([]string, len(src)) copy(dst, src) fmt.Printf(\u0026#34;source slice: %[1]v, address: %[1]p\\n\u0026#34;, src) fmt.Printf(\u0026#34;source slice: %[1]v, address: %[1]p\\n\u0026#34;, dst) } Output:\nsource slice: [a b c], address: 0xc000098180 source slice: [a b c], address: 0xc0000981b0 As you can see, we got two different addresses of underlying arrays for the src and dst slices, which is evidence that we deeply cloned the src slice. The copy() function copies min(len(dst), len(src)) elements, so we need to create the dst slice of the same size as the src using make([]string, len(src)).\nCopy a slice using the append() function #package main import \u0026#34;fmt\u0026#34; func main() { src := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} var dst []string dst = append(dst, src...) fmt.Printf(\u0026#34;source slice: %[1]v, address: %[1]p\\n\u0026#34;, src) fmt.Printf(\u0026#34;source slice: %[1]v, address: %[1]p\\n\u0026#34;, dst) } Output:\nsource slice: [a b c], address: 0xc000098180 source slice: [a b c], address: 0xc0000981b0 Copying a slice using the append() function is really simple. You just need to define a new empty slice, and use the append() to add all elements of the src to the dst slice. In that way, you get a new slice with all the elements duplicated.\nShallow copy by assignment #package main import \u0026#34;fmt\u0026#34; func main() { src := []string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} dst := src fmt.Printf(\u0026#34;source slice: %[1]v, address: %[1]p\\n\u0026#34;, src) fmt.Printf(\u0026#34;source slice: %[1]v, address: %[1]p\\n\u0026#34;, dst) } Output:\nsource slice: [a b c], address: 0xc000098180 source slice: [a b c], address: 0xc000098180 If you just assign the src slice to the new dst variable, you get a shallow copy that has the same underlying array. When you modify the contents of this copy, the original slice will also change.\n","date":"25 November 2021","permalink":"https://gosamples.dev/copy-slice/","section":"Tutorials","summary":"","title":"🧑‍🤝‍🧑 Copy a slice in Go"},{"content":"If you have a slice or an array of strings that contain numbers in your Go application, and you want to sort them in natural order instead of alphabetical order, you need to write your own sorting function using the sort.Slice(). It should convert each element to int or float type and make a number comparison. The result will be a slice of the strings sorted like numbers.\nSort in natural order #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;sort\u0026#34; \u0026#34;strconv\u0026#34; ) func sortNumbers(data []string) ([]string, error) { var lastErr error sort.Slice(data, func(i, j int) bool { a, err := strconv.ParseInt(data[i], 10, 64) if err != nil { lastErr = err return false } b, err := strconv.ParseInt(data[j], 10, 64) if err != nil { lastErr = err return false } return a \u0026lt; b }) return data, lastErr } func main() { data := []string{\u0026#34;10\u0026#34;, \u0026#34;1\u0026#34;, \u0026#34;2\u0026#34;, \u0026#34;8\u0026#34;, \u0026#34;4\u0026#34;, \u0026#34;3\u0026#34;, \u0026#34;9\u0026#34;, \u0026#34;7\u0026#34;, \u0026#34;6\u0026#34;, \u0026#34;5\u0026#34;} sorted, err := sortNumbers(data) if err != nil { log.Fatal(err) } fmt.Println(sorted) } Output:\n[1 2 3 4 5 6 7 8 9 10] As you can see in the sortNumber() function, we return the last error of the two elements comparison. If a given element cannot be converted to a number, it means that the input data is invalid, and the result of sorting may be incorrect. You should handle this error in your application to avoid unexpected results.\nSort in alphabetical order #However, if your goal is to sort the strings alphabetically, just use the sort.Strings() function:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;sort\u0026#34; ) func main() { data := []string{\u0026#34;10\u0026#34;, \u0026#34;1\u0026#34;, \u0026#34;2\u0026#34;, \u0026#34;8\u0026#34;, \u0026#34;4\u0026#34;, \u0026#34;3\u0026#34;, \u0026#34;9\u0026#34;, \u0026#34;7\u0026#34;, \u0026#34;6\u0026#34;, \u0026#34;5\u0026#34;} sort.Strings(data) fmt.Println(data) } Output:\n[1 10 2 3 4 5 6 7 8 9] ","date":"23 November 2021","permalink":"https://gosamples.dev/sort-string-numbers/","section":"Tutorials","summary":"","title":"🧮 Sort a string slice containing numbers in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/sqlite/","section":"Tags","summary":"","title":"Sqlite"},{"content":"To use SQLite in Go, you need a database driver - a client that allows you to connect to and perform operations on the database. Go does not provide any official driver, but it does have a common driver interface for SQL-like databases, defined in the database/sql package. Most SQL databases implementations use it, which allows the same functions to be used for different databases. One of the most popular such drivers for SQLite is mattn/go-sqlite3, and this driver is used in this tutorial to demonstrate how to make basic operations on an SQLite database in Go.\nClick here to go directly to the full code example.\nRepository pattern #When exchanging data with a database, it is a good idea not to mix application logic with database logic. This can be done by abstracting the data access layer into a separate structure, responsible for storing and retrieving data from the database. This pattern is known as a Repository. It allows for:\nReduction of code duplication - you define a data access layer for a given domain object only once. Improving readability of your code - business logic is not mixed with data access logic. Easy addition of new features and modifications to the data access code, and even easy replacement of the entire database, as the code that operates directly on the DB is hidden in a specific repository implementation. We strongly advocate using the Repository to exchange data with the database. This tutorial demonstrates how to create a simple repository and use this pattern to create, read, update and delete data from an SQLite database.\nProject structure #In our example, we want to create a Website repository - a repository that stores information about a particular website - its name, URL, and ranking. Let\u0026rsquo;s start with our project structure tree:\nsqlite-intro/ ├── main.go └── website ├── sqlite_repository.go └── website.go There are two main parts to this project:\nmain.go file - the entry point to our application that initializes the database connection and makes basic operations on a database through the repository. We will present what is inside this file after defining the domain object - Website, and implementing the repository. website package - the package responsible for the Website domain. It contains a definition of the Website struct and the SQLite repository implementation to store Website objects in the SQLite database. Note that we use packaging by feature in our project to have all the structures related to the Website in one place.\nTo use the repository, we need to define it first, so in the next section, we will start by defining the contents of the website package.\nThe website package #website ├── sqlite_repository.go └── website.go Domain object #In the website/website.go file, we define our domain object, a Website, which is a struct that contains data about a given website. Objects of this type will be stored in the database and retrieved from it.\npackage website type Website struct { ID int64 Name string URL string Rank int64 } Repository - constructor, errors and Migrate() function #The next step is to create an SQLite implementation of the Website repository. To do this, we initilize a website/sqlite_repository.go file, where we define an SQLiteRepository struct that will interact with the SQLite database. This struct will have the following methods:\nMigrate() error Create(website Website) (*Website, error) All() ([]Website, error) GetByName(name string) (*Website, error) Update(id int64, updated Website) (*Website, error) Delete(id int64) error Note that the method definitions do not depend on SQLite at all. This is the purpose of the Repository pattern - hiding database implementation details and providing a simple API to interact with any database. In the future, you can define a Repository interface:\ntype Repository interface { Migrate() error Create(website Website) (*Website, error) All() ([]Website, error) GetByName(name string) (*Website, error) Update(id int64, updated Website) (*Website, error) Delete(id int64) error } and add new databases repository implementations, for example, MySQLRepository, PostgresRepository, etc., if you want to change the database in your application. With the Repository pattern, using a different database is just a matter of calling a constructor of a different repository implementation.\nLet\u0026rsquo;s start with the code of the SQLiteRepository constructor, the repository errors definition, and the Migrate() method implementation:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package website import ( \u0026#34;database/sql\u0026#34; \u0026#34;errors\u0026#34; \u0026#34;github.com/mattn/go-sqlite3\u0026#34; ) var ( ErrDuplicate = errors.New(\u0026#34;record already exists\u0026#34;) ErrNotExists = errors.New(\u0026#34;row not exists\u0026#34;) ErrUpdateFailed = errors.New(\u0026#34;update failed\u0026#34;) ErrDeleteFailed = errors.New(\u0026#34;delete failed\u0026#34;) ) type SQLiteRepository struct { db *sql.DB } func NewSQLiteRepository(db *sql.DB) *SQLiteRepository { return \u0026amp;SQLiteRepository{ db: db, } } func (r *SQLiteRepository) Migrate() error { query := ` CREATE TABLE IF NOT EXISTS websites( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, url TEXT NOT NULL, rank INTEGER NOT NULL ); ` _, err := r.db.Exec(query) return err } In lines 17-25, we define the SQLiteRepository struct and its constructor. Note that it requires an instance of sql.DB type as a dependency. The sql.DB is an object representing a pool of DB connections for all drivers compatible with the database/sql interface. In lines 10-15, we define all errors that can be returned by methods of this repository. It is a good practice to return your own defined errors instead of the errors returned by functions of database/sql package or driver-specific errors. This will make the repository driver-independent and easier to modify in the future. In lines 27-39, we create the Migrate() method, which is responsible for migrating the repository. Migration, in this case, is creating an SQL table and initializing all the data necessary to operate on the repository. When working on a fresh database instance, this function should be called first, before reading or writing data through the repository. The logic of the Migrate() is simple - it executes the CREATE TABLE SQL query using DB.Exec() method and returns the error. Create a new record in the SQLite database #After defining SQLiteRepository, its constructor, and the Migrate() method, we want to create a function to write records to the database. This is the purpose of the Create() method, which takes a row to create and returns the row after insertion or an error if the operation fails.\n41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 func (r *SQLiteRepository) Create(website Website) (*Website, error) { res, err := r.db.Exec(\u0026#34;INSERT INTO websites(name, url, rank) values(?,?,?)\u0026#34;, website.Name, website.URL, website.Rank) if err != nil { var sqliteErr sqlite3.Error if errors.As(err, \u0026amp;sqliteErr) { if errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique) { return nil, ErrDuplicate } } return nil, err } id, err := res.LastInsertId() if err != nil { return nil, err } website.ID = id return \u0026amp;website, nil } Like Migrate(), this function uses the DB.Exec() method to execute an SQL INSERT query. If there is an error, we check if it is an instance of sqlite3.Error and if its code indicates an SQLite unique constraint violation. It means that a record with the same UNIQUE field (the same name in the websites table) already exists, so we can map this error to ErrDuplicate, which we defined before. In the last part, we take the inserted record ID and assign it to the returned object so that it reflects the state in the database.\nMany DB methods, like DB.Exec() or DB.Query(), take a query and arguments as input parameters. As you can see in the example above, you need to use the ? character to indicate where the subsequent arguments should be inserted into the query.\nRead from SQLite database #To read Website records from the repository, we use two methods:\nAll() ([]Website, error) which returns all available records in the Website repository GetByName(name string) (*Website, error) that gives back a Website with the specified name 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 func (r *SQLiteRepository) All() ([]Website, error) { rows, err := r.db.Query(\u0026#34;SELECT * FROM websites\u0026#34;) if err != nil { return nil, err } defer rows.Close() var all []Website for rows.Next() { var website Website if err := rows.Scan(\u0026amp;website.ID, \u0026amp;website.Name, \u0026amp;website.URL, \u0026amp;website.Rank); err != nil { return nil, err } all = append(all, website) } return all, nil } func (r *SQLiteRepository) GetByName(name string) (*Website, error) { row := r.db.QueryRow(\u0026#34;SELECT * FROM websites WHERE name = ?\u0026#34;, name) var website Website if err := row.Scan(\u0026amp;website.ID, \u0026amp;website.Name, \u0026amp;website.URL, \u0026amp;website.Rank); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotExists } return nil, err } return \u0026amp;website, nil } The All() method uses the DB.Query() to return rows for the SQL SELECT query. The difference between the DB.Query() and DB.Exec() methods is that the former is used for the queries that return rows, the latter for the queries that do not. As the result of the DB.Query(), we get an sql.Rows struct that represents a cursor to SQL rows. Notice that it should be closed at the end of the function. Using two methods: Next() returning true if there are more rows in the result, and Scan() that copies successive values of the result set into the given variables, we can create a slice of all websites in the database table.\nThe GetByName() method works in a similar way, but instead of DB.Query() it uses DB.QueryRow() that returns at most one row. This eliminates the need to close the structure. To copy values to a Website object, we use the same Scan() method as before. We also check if the Scan() returns a standard sql.ErrNoRows error if there is no record in the result. In such a case, we map this error to our repository ErrNotExists error.\nUpdate a row of the SQLite database #The Update() method is not significantly different from the previous ones. It uses the DB.Exec() to execute the SQL UPDATE query that replaces values for a record with a given ID. It then checks how many rows were affected by this update. If zero, we consider it failed and return the ErrUpdateFailed error.\n93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 func (r *SQLiteRepository) Update(id int64, updated Website) (*Website, error) { if id == 0 { return nil, errors.New(\u0026#34;invalid updated ID\u0026#34;) } res, err := r.db.Exec(\u0026#34;UPDATE websites SET name = ?, url = ?, rank = ? WHERE id = ?\u0026#34;, updated.Name, updated.URL, updated.Rank, id) if err != nil { return nil, err } rowsAffected, err := res.RowsAffected() if err != nil { return nil, err } if rowsAffected == 0 { return nil, ErrUpdateFailed } return \u0026amp;updated, nil } Delete a row from the SQLite database #The Delete() method works similarly to Update(). It executes the SQL DELETE query to delete the row with the specified ID from the database. If no row is affected, it returns the ErrUpdateFailed error.\n114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 func (r *SQLiteRepository) Delete(id int64) error { res, err := r.db.Exec(\u0026#34;DELETE FROM websites WHERE id = ?\u0026#34;, id) if err != nil { return err } rowsAffected, err := res.RowsAffected() if err != nil { return err } if rowsAffected == 0 { return ErrDeleteFailed } return err } In this way, we have created a complete SQLite repository with CRUD operations. Now it\u0026rsquo;s time to test it by creating a simple app that demonstrates how its functions work.\nThe main() function #Connect to SQLite # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package main import ( \u0026#34;database/sql\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;github.com/gosamples-dev/samples/sqlite-intro/website\u0026#34; _ \u0026#34;github.com/mattn/go-sqlite3\u0026#34; ) const fileName = \u0026#34;sqlite.db\u0026#34; func main() { os.Remove(fileName) db, err := sql.Open(\u0026#34;sqlite3\u0026#34;, fileName) if err != nil { log.Fatal(err) } // ... To connect to an SQLite database using the mattn/go-sqlite3 driver, it is necessary to register it as the database/sql driver. It is done by importing the driver package in line 10 (we do this using a blank identifier, to import the package, even though it is not used by the current program). Once imported, it calls the init() function, which registers the driver in the database/sql interface under the name sqlite3. Using the sql.Open() function with the registered sqlite3 driver name, you can connect to a new SQLite database. The second argument is the data source name which in the case of SQLite is a path to the database file. In our example, we want to run the program with a fresh instance each time, so the first line of main() deletes the old database file if it exists. Init the SQLite repository # 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 websiteRepository := website.NewSQLiteRepository(db) if err := websiteRepository.Migrate(); err != nil { log.Fatal(err) } gosamples := website.Website{ Name: \u0026#34;GOSAMPLES\u0026#34;, URL: \u0026#34;https://gosamples.dev\u0026#34;, Rank: 2, } golang := website.Website{ Name: \u0026#34;Golang official website\u0026#34;, URL: \u0026#34;https://golang.org\u0026#34;, Rank: 1, } createdGosamples, err := websiteRepository.Create(gosamples) if err != nil { log.Fatal(err) } createdGolang, err := websiteRepository.Create(golang) if err != nil { log.Fatal(err) } In lines 23-27, we create a new website SQLite repository and migrate the data, which in our case means that we create a new SQL websites table. In lines 29-47, we create new Website objects and insert them into the database using the Create() method. Read, update, delete in the repository # 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 gotGosamples, err := websiteRepository.GetByName(\u0026#34;GOSAMPLES\u0026#34;) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;get by name: %+v\\n\u0026#34;, gotGosamples) createdGosamples.Rank = 1 if _, err := websiteRepository.Update(createdGosamples.ID, *createdGosamples); err != nil { log.Fatal(err) } all, err := websiteRepository.All() if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;\\nAll websites:\\n\u0026#34;) for _, website := range all { fmt.Printf(\u0026#34;website: %+v\\n\u0026#34;, website) } if err := websiteRepository.Delete(createdGolang.ID); err != nil { log.Fatal(err) } all, err = websiteRepository.All() if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;\\nAll websites:\\n\u0026#34;) for _, website := range all { fmt.Printf(\u0026#34;website: %+v\\n\u0026#34;, website) } In lines 49-54, we retrieve the record with the GOSAMPLES name from the database and print it to the console. In lines 56-69, we make a ranking update of the retrieved record and then get all records from the table to ensure that the update was performed successfully. In lines 71-82, we delete the second row by ID, and also get and print all records to ensure that the database state is correct. Follow the output below to check the results of these operations:\nget by name: \u0026amp;{ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:2} All websites: website: {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} website: {ID:2 Name:Golang official website URL:https://golang.org Rank:1} All websites: website: {ID:1 Name:GOSAMPLES URL:https://gosamples.dev Rank:1} As you can see, using SQLite in Go is really simple and no different than using MySQL, Postgres, or any other SQL database, thanks to the common database/sql interface. By using the Repository pattern, you can also make the code clean and easy to understand, where the business and data access logic are not mixed.\nFull example #The example is also available on Github here.\nwebsite/website.go\n1 2 3 4 5 6 7 8 package website type Website struct { ID int64 Name string URL string Rank int64 } website/sqlite_repository.go\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 package website import ( \u0026#34;database/sql\u0026#34; \u0026#34;errors\u0026#34; \u0026#34;github.com/mattn/go-sqlite3\u0026#34; ) var ( ErrDuplicate = errors.New(\u0026#34;record already exists\u0026#34;) ErrNotExists = errors.New(\u0026#34;row not exists\u0026#34;) ErrUpdateFailed = errors.New(\u0026#34;update failed\u0026#34;) ErrDeleteFailed = errors.New(\u0026#34;delete failed\u0026#34;) ) type SQLiteRepository struct { db *sql.DB } func NewSQLiteRepository(db *sql.DB) *SQLiteRepository { return \u0026amp;SQLiteRepository{ db: db, } } func (r *SQLiteRepository) Migrate() error { query := ` CREATE TABLE IF NOT EXISTS websites( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, url TEXT NOT NULL, rank INTEGER NOT NULL ); ` _, err := r.db.Exec(query) return err } func (r *SQLiteRepository) Create(website Website) (*Website, error) { res, err := r.db.Exec(\u0026#34;INSERT INTO websites(name, url, rank) values(?,?,?)\u0026#34;, website.Name, website.URL, website.Rank) if err != nil { var sqliteErr sqlite3.Error if errors.As(err, \u0026amp;sqliteErr) { if errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique) { return nil, ErrDuplicate } } return nil, err } id, err := res.LastInsertId() if err != nil { return nil, err } website.ID = id return \u0026amp;website, nil } func (r *SQLiteRepository) All() ([]Website, error) { rows, err := r.db.Query(\u0026#34;SELECT * FROM websites\u0026#34;) if err != nil { return nil, err } defer rows.Close() var all []Website for rows.Next() { var website Website if err := rows.Scan(\u0026amp;website.ID, \u0026amp;website.Name, \u0026amp;website.URL, \u0026amp;website.Rank); err != nil { return nil, err } all = append(all, website) } return all, nil } func (r *SQLiteRepository) GetByName(name string) (*Website, error) { row := r.db.QueryRow(\u0026#34;SELECT * FROM websites WHERE name = ?\u0026#34;, name) var website Website if err := row.Scan(\u0026amp;website.ID, \u0026amp;website.Name, \u0026amp;website.URL, \u0026amp;website.Rank); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotExists } return nil, err } return \u0026amp;website, nil } func (r *SQLiteRepository) Update(id int64, updated Website) (*Website, error) { if id == 0 { return nil, errors.New(\u0026#34;invalid updated ID\u0026#34;) } res, err := r.db.Exec(\u0026#34;UPDATE websites SET name = ?, url = ?, rank = ? WHERE id = ?\u0026#34;, updated.Name, updated.URL, updated.Rank, id) if err != nil { return nil, err } rowsAffected, err := res.RowsAffected() if err != nil { return nil, err } if rowsAffected == 0 { return nil, ErrUpdateFailed } return \u0026amp;updated, nil } func (r *SQLiteRepository) Delete(id int64) error { res, err := r.db.Exec(\u0026#34;DELETE FROM websites WHERE id = ?\u0026#34;, id) if err != nil { return err } rowsAffected, err := res.RowsAffected() if err != nil { return err } if rowsAffected == 0 { return ErrDeleteFailed } return err } main.go\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 package main import ( \u0026#34;database/sql\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;github.com/gosamples-dev/samples/sqlite-intro/website\u0026#34; _ \u0026#34;github.com/mattn/go-sqlite3\u0026#34; ) const fileName = \u0026#34;sqlite.db\u0026#34; func main() { os.Remove(fileName) db, err := sql.Open(\u0026#34;sqlite3\u0026#34;, fileName) if err != nil { log.Fatal(err) } websiteRepository := website.NewSQLiteRepository(db) if err := websiteRepository.Migrate(); err != nil { log.Fatal(err) } gosamples := website.Website{ Name: \u0026#34;GOSAMPLES\u0026#34;, URL: \u0026#34;https://gosamples.dev\u0026#34;, Rank: 2, } golang := website.Website{ Name: \u0026#34;Golang official website\u0026#34;, URL: \u0026#34;https://golang.org\u0026#34;, Rank: 1, } createdGosamples, err := websiteRepository.Create(gosamples) if err != nil { log.Fatal(err) } createdGolang, err := websiteRepository.Create(golang) if err != nil { log.Fatal(err) } gotGosamples, err := websiteRepository.GetByName(\u0026#34;GOSAMPLES\u0026#34;) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;get by name: %+v\\n\u0026#34;, gotGosamples) createdGosamples.Rank = 1 if _, err := websiteRepository.Update(createdGosamples.ID, *createdGosamples); err != nil { log.Fatal(err) } all, err := websiteRepository.All() if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;\\nAll websites:\\n\u0026#34;) for _, website := range all { fmt.Printf(\u0026#34;website: %+v\\n\u0026#34;, website) } if err := websiteRepository.Delete(createdGolang.ID); err != nil { log.Fatal(err) } all, err = websiteRepository.All() if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;\\nAll websites:\\n\u0026#34;) for _, website := range all { fmt.Printf(\u0026#34;website: %+v\\n\u0026#34;, website) } } ","date":"22 November 2021","permalink":"https://gosamples.dev/sqlite-intro/","section":"Tutorials","summary":"","title":"🗂️ Introductory tutorial to SQLite in Go"},{"content":"Go does not provide a language construct or a standard library function to check whether a given value is in a slice. To do this, you need to write your own contains() function that takes two arguments: the slice and the element to find. As a result, it should return true if the slice contains this element and false otherwise.\npackage main import \u0026#34;fmt\u0026#34; func contains(elems []string, v string) bool { for _, s := range elems { if v == s { return true } } return false } func main() { fmt.Println(contains([]string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;}, \u0026#34;b\u0026#34;)) fmt.Println(contains([]string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;}, \u0026#34;d\u0026#34;)) } Output:\ntrue false If you want to operate on a slice of a different type, you must implement a separate function. For example, for int64, the function would look like this:\nfunc contains(elems []int64, v int64) bool { for _, s := range elems { if v == s { return true } } return false } This function works well if your slice is not too large. For longer lists of data, you should consider using a map for storage, which has generally much better lookup performance than iterating over slices.\nGo Programming Language Specification does not make any complexity guarantees but in general map lookup should have a complexity of O(1), while finding an element in a slice is O(n).\n","date":"5 November 2021","permalink":"https://gosamples.dev/slice-contains/","section":"Tutorials","summary":"","title":"🔎 Check if the slice contains the given value in Go"},{"content":"In Go, there are several methods for string concatenation. The simplest one (but not the best one) is to add two strings using the plus (+) operator. You can also use the fmt.Sprintf() function if you have a couple of strings that want to combine into one. A more efficient way to concatenate strings is to use the strings.Builder structure which minimizes memory copying and is recommended for building longer results. Alternatively, you can also use the strings.Join() function if you know all the strings to join and their separator before calling it, or bytes.Buffer and byte slices to operate directly on string bytes.\nThere is no single best method to concatenate strings, so it is a good idea to know most of them, their pros and cons, and use them depending on your use case.\nAll benchmarks in the examples below were run in Go 1.17.\nUse the plus (+) operator to simply concatenate strings #Using the plus (+) operator is the simplest way of strings concatenation. However, you should be careful when calling this method because strings in Go are immutable, and every time you add a string to an existing variable, a new string is allocated in memory. As a result, this method is inefficient if you need to concatenate multiple strings, for example, in a loop. In that case, you should use the strings.Builder method to build the final string.\nThis and all the following examples give the output: Hello https://gosamples.dev 😉.\npackage main import \u0026#34;fmt\u0026#34; func main() { hello := \u0026#34;Hello\u0026#34; gosamples := \u0026#34;https://gosamples.dev\u0026#34; result := hello result += \u0026#34; \u0026#34; result += gosamples fmt.Println(result) } Pros and cons of concatenating strings using the plus (+) operator:\nThe easiest way of concatenating strings\nNo need to use external dependencies\nInefficient when used to concatenate a long list of strings\n✗ Less readable than fmt.Sprintf() method when building a formatted string Use the fmt.Sprintf() function to format multiple strings into one #The fmt.Sprintf() function takes a template and arguments and returns this template with the appropriate fields replaced by the arguments. This is the most idiomatic and readable method for creating short strings with variable values but is not suitable for concatenation when you do not know the number of strings in advance.\npackage main import \u0026#34;fmt\u0026#34; func main() { hello := \u0026#34;Hello\u0026#34; gosamples := \u0026#34;https://gosamples.dev\u0026#34; result := fmt.Sprintf(\u0026#34;%s %s\u0026#34;, hello, gosamples) fmt.Println(result) } Pros and cons of concatenating strings using the fmt.Sprintf() function:\nA clear and idiomatic way of creating strings with variable values\nAllows to easily create strings from arguments of different types e.g. string, int, bool, etc., without explicit conversion\nNot suitable when you do not know in advance the number of elements to concatenate\n✗ Inconvenient for a longer list of arguments Use strings.Builder to efficiently concatenate strings #The strings.Builder was created to build long strings in a simple and efficient way. This method minimizes the number of copies and memory allocations and works particularly well if you have a large list of strings to concatenate or if the process of building the resulting string is multi-step. If you need to perform string concatenation efficiently, this method is the most recommended and natural choice in Go.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;strings\u0026#34; ) func main() { data := []string{\u0026#34;Hello\u0026#34;, \u0026#34; \u0026#34;, \u0026#34;https://gosamples.dev\u0026#34;} var builder strings.Builder for _, s := range data { _, err := builder.WriteString(s) if err != nil { log.Fatal(err) } } fmt.Println(builder.String()) } If you know the size of the output in advance, it is a good practice to use the Grow() method to preallocate the needed memory. This increases the speed of concatenation by avoiding unnecessary copying of partial results:\nbuilder.Grow(27) Pros and cons of concatenating strings using the strings.Builder:\nEfficient for concatenating a long list of strings or for building a string in multiple steps\nMore complicated to use than the previous methods\nUse the strings.Join() function to create a single string from a slice #The strings.Join() constructs a single string from joining a fixed slice of strings with a defined separator between them. It uses the strings.Builder internally. Since the number of elements to be concatenated is known, it allocates the necessary amount of memory, which makes this method very efficient.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { hello := \u0026#34;Hello\u0026#34; gosamples := \u0026#34;https://gosamples.dev\u0026#34; result := strings.Join([]string{hello, gosamples}, \u0026#34; \u0026#34;) fmt.Println(result) } Pros and cons of concatenating strings using the strings.Join() function:\nSuper-efficient for concatenating a fixed list of strings with the same separator\nSimple and easy to use\nNot suitable when you do not know in advance the number of elements to concatenate or if you want to use different separators\nUse bytes.Buffer to efficiently build a byte buffer #The strings.Builder was introduced in Go 1.10. Before that, the bytes.Buffer was used to concatenate strings efficiently. It has similar methods but is slightly slower, so in the new code, you should use the strings.Builder instead.\npackage main import ( \u0026#34;bytes\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { data := []string{\u0026#34;Hello\u0026#34;, \u0026#34; \u0026#34;, \u0026#34;https://gosamples.dev\u0026#34;} var buffer bytes.Buffer for _, s := range data { _, err := buffer.WriteString(s) if err != nil { log.Fatal(err) } } fmt.Println(buffer.String()) } As with the strings.Builder, you can use the Grow() method to preallocate the needed memory:\nbuffer.Grow(27) Pros and cons of concatenating strings using the bytes.Buffer:\nEfficient for concatenating a long list of strings or for building a string in multiple steps\n✗ Since Go 1.10, there is the strings.Builder which has similar methods and is more efficient Use byte slice to extend a string #Strings in Go are read-only slices of bytes, so there is no problem extending a byte slice of a string by appending bytes of another string. As a result, after converting to a string, we get the concatenated output. However, this method is low-level and less idiomatic than the others. In practice, it is much better to use the strings.Builder instead.\npackage main import ( \u0026#34;fmt\u0026#34; ) func main() { data := []string{\u0026#34;Hello\u0026#34;, \u0026#34; \u0026#34;, \u0026#34;https://gosamples.dev\u0026#34;} var byteSlice []byte for _, s := range data { byteSlice = append(byteSlice, []byte(s)...) } fmt.Println(string(byteSlice)) } Pros and cons of concatenating strings using appending to a byte slice:\nEasy to use\nDo not require any dependencies\n✗ Works on byte slices instead of strings - requires final conversion to string\n✗ Not as efficient as the bytes.Buffer\nBenchmarks #To check which method of concatenating strings is the fastest, we prepared a simple benchmark that compares all the above methods. Each of them concatenates 399 elements into a single result. We simulated two variants of concatenation: when we know the size of the result string in advance (benchmarks named Benchmark\u0026lt;XXX\u0026gt;KnownSize), and when we do not know the exact size of the result string (benchmarks named Benchmark\u0026lt;XXX\u0026gt;UnknownSize). We did this because some methods are only suitable when we know the number of elements to concatenate (strings.Join(), fmt.Sprintf()), some work without considering the number of elements (the plus (+) operator), and some work in both variants (strings.Builder, bytes.Buffer, byte slice):\nstrings.Join() requires a slice of strings as an argument, so the number of elements to concatenate must be known before calling this function. fmt.Sprintf() works for a finite and known number of arguments equal to the number of arguments in the template. the plus (+) operator concatenates only one argument at a time (result += argument), and you cannot specify how many elements you have or preallocate a fixed amount of memory for the result. strings.Builder and bytes.Buffer can build strings when we do not know the number of elements that will finally be in the result. When necessary, they allocate more memory for the output. Therefore, these methods work well for creating strings dynamically, for example, in a loop. On the other hand, when we know the number of elements to concatenate and the size of the result, we can immediately allocate the needed amount of memory using the Grow() method (available in strings.Builder as well as in bytes.Buffer), avoiding unnecessary copying of partial results. byte slices, like strings.Builder and bytes.Buffer, can be initialized as empty using var byteSlice []byte or with a specified capacity using byteSlice := make([]byte, 0, size). In this way, this method can be used both with a known number of elements and without specifying the size of the result. The fastest method does not mean the best. Always consider the readability of the code and try to fit the method to the use case.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 package benchmark import ( \u0026#34;bytes\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;testing\u0026#34; ) const ( hello = \u0026#34;hello\u0026#34; gosamples = \u0026#34;https://gosamples.dev\u0026#34; ) func generateStrings(withSeparator bool) (data []string, size int) { for i := 0; i \u0026lt; 100; i++ { data = append(data, hello) size += len(hello) if withSeparator { data = append(data, \u0026#34; \u0026#34;) size++ } data = append(data, gosamples) size += len(gosamples) if withSeparator { data = append(data, \u0026#34; \u0026#34;) size++ } } if withSeparator { data = data[:len(data)-1] size-- } return data, size } func BenchmarkPlusOperatorUnknownSize(b *testing.B) { data, _ := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { for _, d := range data { s += d } _ = s } } func BenchmarkSprintfKnownSize(b *testing.B) { data, _ := generateStrings(false) var interfaceData []interface{} for _, d := range data { interfaceData = append(interfaceData, d) } format := strings.Repeat(\u0026#34;%s \u0026#34;, len(interfaceData)) format = strings.TrimSuffix(format, \u0026#34; \u0026#34;) var s string for n := 0; n \u0026lt; b.N; n++ { s = fmt.Sprintf(format, interfaceData...) _ = s } } func BenchmarkStringBuilderUnknownSize(b *testing.B) { data, _ := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { var builder strings.Builder for _, s := range data { builder.WriteString(s) } s = builder.String() _ = s } } func BenchmarkStringBuilderKnownSize(b *testing.B) { data, size := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { var builder strings.Builder builder.Grow(size) for _, s := range data { builder.WriteString(s) } s = builder.String() _ = s } } func BenchmarkJoinKnownSize(b *testing.B) { data, _ := generateStrings(false) var s string for n := 0; n \u0026lt; b.N; n++ { s = strings.Join(data, \u0026#34; \u0026#34;) _ = s } } func BenchmarkBytesBufferUnknownSize(b *testing.B) { data, _ := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { var buffer bytes.Buffer for _, s := range data { buffer.WriteString(s) } s = buffer.String() _ = s } } func BenchmarkBytesBufferKnownSize(b *testing.B) { data, size := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { var buffer bytes.Buffer buffer.Grow(size) for _, s := range data { buffer.WriteString(s) } s = buffer.String() _ = s } } func BenchmarkByteSliceUnknownSize(b *testing.B) { data, _ := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { var byteSlice []byte for _, s := range data { byteSlice = append(byteSlice, []byte(s)...) } s = string(byteSlice) _ = s } } func BenchmarkByteSliceKnownSize(b *testing.B) { data, size := generateStrings(true) var s string for n := 0; n \u0026lt; b.N; n++ { byteSlice := make([]byte, 0, size) for _, s := range data { byteSlice = append(byteSlice, []byte(s)...) } s = string(byteSlice) _ = s } } Running the benchmark with the command:\ngo test -bench=. we got the results:\nBenchmarkPlusOperatorUnknownSize-8 166 12008232 ns/op BenchmarkSprintfKnownSize-8 184053 6421 ns/op BenchmarkStringBuilderUnknownSize-8 269620 4365 ns/op BenchmarkStringBuilderKnownSize-8 422790 2735 ns/op BenchmarkJoinKnownSize-8 475293 2370 ns/op BenchmarkBytesBufferUnknownSize-8 219260 5441 ns/op BenchmarkBytesBufferKnownSize-8 321973 3639 ns/op BenchmarkByteSliceUnknownSize-8 175533 6803 ns/op BenchmarkByteSliceKnownSize-8 230568 5046 ns/op The benchmark is also available as a Github Gist.\nAs you can see, the plus (+) operator is much slower than the other methods, and you should not use them to concatenate a longer list of elements. In terms of performance, it is best to use the strings.Builder or strings.Join() to join a long list of strings. In our case, strings.Join() turned out to be even faster than the strings.Builder. You get a big speedup when you preallocate the amount of memory necessary for the output. The bytes.Buffer and byte slice methods are slower and not as readable as the strings.Builder because they operate on bytes rather than strings. So, they should not be your first choice for string concatenation. ","date":"31 October 2021","permalink":"https://gosamples.dev/concatenate-strings/","section":"Tutorials","summary":"","title":"🍒 Concatenate strings in Go"},{"content":"The connection reset by peer is a TCP/IP error that occurs when the other end (peer) has unexpectedly closed the connection. It happens when you send a packet from your end, but the other end crashes and forcibly closes the connection with the RST packet instead of the TCP FIN, which is used to close a connection under normal circumstances. In Go, you can detect the connection reset by peer by checking if the error returned by the peer is equal to syscall.ECONNRESET.\nReproduce the connection reset by peer error #We can reproduce the error by creating a server and client that do the following:\nthe server reads a single byte and then closes the connection the client sends more than one byte If the server closes the connection with the remaining bytes in the socket\u0026rsquo;s receive buffer, then an RST packet is sent to the client. When the client tries to read from such a closed connection, it will get the connection reset by peer error.\nSee the following example, which simulates this behavior.\npackage main import ( \u0026#34;errors\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net\u0026#34; \u0026#34;os\u0026#34; \u0026#34;syscall\u0026#34; \u0026#34;time\u0026#34; ) func server() { listener, err := net.Listen(\u0026#34;tcp\u0026#34;, \u0026#34;:8080\u0026#34;) if err != nil { log.Fatal(err) } defer listener.Close() conn, err := listener.Accept() if err != nil { log.Fatal(\u0026#34;server\u0026#34;, err) os.Exit(1) } data := make([]byte, 1) if _, err := conn.Read(data); err != nil { log.Fatal(\u0026#34;server\u0026#34;, err) } conn.Close() } func client() { conn, err := net.Dial(\u0026#34;tcp\u0026#34;, \u0026#34;localhost:8080\u0026#34;) if err != nil { log.Fatal(\u0026#34;client\u0026#34;, err) } if _, err := conn.Write([]byte(\u0026#34;ab\u0026#34;)); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) } time.Sleep(1 * time.Second) // wait for close on the server side data := make([]byte, 1) if _, err := conn.Read(data); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) if errors.Is(err, syscall.ECONNRESET) { log.Print(\u0026#34;This is connection reset by peer error\u0026#34;) } } } func main() { go server() time.Sleep(3 * time.Second) // wait for server to run client() } Output:\n2021/10/20 19:01:58 client: read tcp [::1]:59897-\u0026gt;[::1]:8080: read: connection reset by peer 2021/10/20 19:01:58 This is connection reset by peer error Handle the connection reset by peer error #Typically, you can see the connection reset by peer error in response to a request being sent from the client to the server. It means that something bad has happened to the server: it has rebooted, the program has crashed, or other problems have occurred that cause the connection to be forcibly closed. Since TCP connections can be broken, there is no need to handle the connection reset by peer in any special way on the client side. You can log the error, ignore it or retry the connection when it occurs. In the example above, we detect the error using the errors.Is() function by checking if the returned error is an instance of syscall.ECONNRESET.\nDifference between connection reset by peer and broken pipe #Both connection reset by peer and broken pipe errors occur when a peer (the other end) unexpectedly closes the underlying connection. However, there is a subtle difference between them. Usually, you get the connection reset by peer when you read from the connection after the server sends the RST packet, and when you write to the connection after the RST instead, you get the broken pipe error.\nCheck how to handle the broken pipe error in Go post, where will find another example of generating an RST packet and the broken pipe error.\nReplace the client() function in the example above with the following code to reproduce the broken pipe error.\nfunc client() { conn, err := net.Dial(\u0026#34;tcp\u0026#34;, \u0026#34;localhost:8080\u0026#34;) if err != nil { log.Fatal(\u0026#34;client\u0026#34;, err) } if _, err := conn.Write([]byte(\u0026#34;ab\u0026#34;)); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) } time.Sleep(1 * time.Second) // wait for close on the server side if _, err := conn.Write([]byte(\u0026#34;b\u0026#34;)); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) } } With the new client, you will see the output:\n2021/10/20 19:55:40 client: write tcp [::1]:60399-\u0026gt;[::1]:8080: write: broken pipe Note that these simple examples do not cover all cases where connection reset by peer and broken pipe may occur. There are much more situations where you can see these errors, and what error you see in what situation requires a deep understanding of the TCP design.\n","date":"21 October 2021","permalink":"https://gosamples.dev/connection-reset-by-peer/","section":"Tutorials","summary":"","title":"🔌 Handle 'connection reset by peer' error in Go"},{"content":"To decode a Base64 encoded string, use the DecodeString() function from the encoding/base64 standard library package. This function takes an encoded string as an argument and returns a byte slice, along with the decoding error. To get the decoded string, convert the byte slice to a string.\nCheck also how to encode a string to Base64 in Go.\npackage main import ( \u0026#34;encoding/base64\u0026#34; \u0026#34;fmt\u0026#34; ) func main() { rawDecodedText, err := base64.StdEncoding.DecodeString(\u0026#34;aGVsbG8gZnJvbSBnb3NhbXBsZXMuZGV2IGJhc2U2NCBlbmNvZGluZyBleGFtcGxlIQ==\u0026#34;) if err != nil { panic(err) } fmt.Printf(\u0026#34;Decoded text: %s\\n\u0026#34;, rawDecodedText) } Output:\nDecoded text: hello from gosamples.dev base64 encoding example! The StdEncoding is an object representing the standard base64 encoding, as defined in RFC 4648, and the DecodeString() is its method.\n","date":"14 October 2021","permalink":"https://gosamples.dev/decode-base64/","section":"Tutorials","summary":"","title":"👈 Decode Base64 to a string in Go"},{"content":"To encode a string to Base64 in Go, use the EncodeToString() function from the encoding/base64 standard library package. This function takes a byte slice and converts it to a Base64 encoded string, but it can also be used for a string argument by converting it to a byte slice.\nCheck also how to decode Base64 to a string in Go.\npackage main import ( \u0026#34;encoding/base64\u0026#34; \u0026#34;fmt\u0026#34; ) func main() { text := \u0026#34;hello from gosamples.dev base64 encoding example!\u0026#34; encodedText := base64.StdEncoding.EncodeToString([]byte(text)) fmt.Printf(\u0026#34;Encoded text: %s\\n\u0026#34;, encodedText) } Output:\nEncoded text: aGVsbG8gZnJvbSBnb3NhbXBsZXMuZGV2IGJhc2U2NCBlbmNvZGluZyBleGFtcGxlIQ== The EncodeToString() is a method of StdEncoding which is an object representing the standard base64 encoding, as defined in RFC 4648.\n","date":"14 October 2021","permalink":"https://gosamples.dev/encode-base64/","section":"Tutorials","summary":"","title":"👉 Encode a string to Base64 in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/base64/","section":"Tags","summary":"","title":"Base64"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/encoding/","section":"Tags","summary":"","title":"Encoding"},{"content":"To convert a string to a byte slice in Go, use the standard []byte conversion expression []byte(string). To convert a byte slice to a string, use the string([]byte) conversion.\nConvert a string to a byte slice #package main import \u0026#34;fmt\u0026#34; func main() { // string to []byte data := []byte(\u0026#34;Hello on https://gosamples.dev\u0026#34;) fmt.Println(data) } Output:\n[72 101 108 108 111 32 111 110 32 104 116 116 112 115 58 47 47 103 111 115 97 109 112 108 101 115 46 100 101 118] Convert a byte slice to a string #package main import \u0026#34;fmt\u0026#34; func main() { // []byte to string str := string([]byte{72, 101, 108, 108, 111, 32, 111, 110, 32, 104, 116, 116, 112, 115, 58, 47, 47, 103, 111, 115, 97, 109, 112, 108, 101, 115, 46, 100, 101, 118}) fmt.Println(str) } Output:\nHello on https://gosamples.dev The difference between a string and a byte slice #The conversion between a string and a byte slice is so simple because a string is technically a read-only slice of bytes. You can take a fragment of a string just like a fragment of a slice or an array:\ns := \u0026#34;GOSAMPLES.dev is the best Golang website in the world!\u0026#34; fmt.Println(s[:13]) Output:\nGOSAMPLES.dev But you can\u0026rsquo;t modify a string:\ns := \u0026#34;🌈 GOSAMPLES.dev\u0026#34; s[5] = 32 // compiler error: cannot assign to s[5] (strings are immutable) fmt.Println(s) A byte slice can be modified:\ns := []byte(\u0026#34;🌈 GOSAMPLES.dev\u0026#34;) s[5] = 32 fmt.Println(string(s)) Output\n🌈 OSAMPLES.dev You can also loop over the individual bytes of a string in the same way as with a byte slice, using the for loop. The examples:\ns := \u0026#34;🌈 GOSAMPLES.dev\u0026#34; for i := 0; i \u0026lt; len(s); i++ { fmt.Println(i, s[i]) } and\nb := []byte(\u0026#34;🌈 GOSAMPLES.dev\u0026#34;) for i := 0; i \u0026lt; len(b); i++ { fmt.Println(i, b[i]) } return the same output:\n0 240 1 159 2 140 3 136 4 32 5 71 6 79 7 83 8 65 9 77 10 80 11 76 12 69 13 83 14 46 15 100 16 101 17 118 You may wonder why the 13-character text is 18 bytes long. This is because the character 🌈 is encoded with 4 bytes in UTF-8 (all strings in Go are UTF-8). For texts containing characters encoded with more than 1 byte, there is another difference between using strings and byte slices, in the behavior of the for range loop. When you use the for range loop on a string, you iterate over runes (Unicode code points):\ns := \u0026#34;🌈 GOSAMPLES.dev\u0026#34; for i, c := range s { fmt.Printf(\u0026#34;%d: %c\\n\u0026#34;, i, c) } Output:\n0: 🌈 4: 5: G 6: O 7: S 8: A 9: M 10: P 11: L 12: E 13: S 14: . 15: d 16: e 17: v When you use the for range on a byte slice, you iterate over individual bytes:\nb := []byte(\u0026#34;🌈 GOSAMPLES.dev\u0026#34;) for i, c := range b { fmt.Printf(\u0026#34;%d: %c\\n\u0026#34;, i, c) } Output:\n0: ð 1: 3: 4: 5: G 6: O 7: S 8: A 9: M 10: P 11: L 12: E 13: S 14: . 15: d 16: e 17: v ","date":"13 October 2021","permalink":"https://gosamples.dev/string-byte-slice/","section":"Tutorials","summary":"","title":"🖨️ Convert string to []byte or []byte to string in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/pointer/","section":"Tags","summary":"","title":"Pointer"},{"content":"In Go, to print the memory address of a variable, struct, array, slice, map, or any other structure, you need to generate a pointer to the value with the address operator \u0026amp; and use the fmt.Println() function (or any other print function from the fmt package) to write the value address to the standard output. If you want to put the address as part of the text, you can use the %p format verb in the fmt.Printf() function.\nExample 1: Print the address of a variable #// variable i := 32 fmt.Println(\u0026amp;i) // pointer to the variable p := \u0026amp;i fmt.Println(p) Output:\n0xc00001c088 0xc00001c088 Example 2: Format the address of a variable #// variable i := 32 fmt.Printf(\u0026#34;Address of i=%d:\\t%p\\n\u0026#34;, i, \u0026amp;i) // pointer to the variable p := \u0026amp;i fmt.Printf(\u0026#34;Address of p=\u0026amp;i=%d:\\t%p\\n\u0026#34;, *p, p) Output:\nAddress of i=32: 0xc00001c088 Address of p=\u0026amp;i=32: 0xc00001c088 Example 3: Format addresses of various Go data structures: array, slice, struct, struct field, and map #package main import \u0026#34;fmt\u0026#34; type A struct { Number int Text string } func main() { // array arr := [3]int{1, 2, 3} fmt.Printf(\u0026#34;Address of array = %v: %p\\n\u0026#34;, arr, \u0026amp;arr) // slice slice := []int{1, 2, 3} fmt.Printf(\u0026#34;Address of slice = %v: %p\\n\u0026#34;, slice, \u0026amp;slice) // struct structInstance := A{Number: 23, Text: \u0026#34;abc\u0026#34;} fmt.Printf(\u0026#34;Address of struct = %+v: %p\\n\u0026#34;, structInstance, \u0026amp;structInstance) // struct field fmt.Printf(\u0026#34;Address of struct field = %s: %p\\n\u0026#34;, structInstance.Text, \u0026amp;structInstance.Text) // map mapInstance := map[int]int{ 0: 1, } fmt.Printf(\u0026#34;Address of map = %v: %p\\n\u0026#34;, mapInstance, \u0026amp;mapInstance) } Output:\nAddress of array = [1 2 3]: 0xc0000b4000 Address of slice = [1 2 3]: 0xc0000a4018 Address of struct = {Number:23 Text:abc}: 0xc0000a4048 Address of struct field = abc: 0xc0000a4050 Address of map = map[0:1]: 0xc0000aa020 As you may know, map index expressions are not addressable, so it is not possible to print the address of a map value with a specific key.\nPrint the address of a pointer #In Example 1 and Example 2, we created a new pointer p of type *int and assigned to it the address of variable i. Then, we printed the value of the pointer p with fmt.Println(p), which is the address of the variable i. Since the pointer itself is a value, we can also print the address of that value using fmt.Println(\u0026amp;p). Compare outputs of printing the address of the variable i, the value of p, and the pointer of p:\n// get the address of a variable i := 32 fmt.Printf(\u0026#34;Address of i=%d: %p\\n\u0026#34;, i, \u0026amp;i) // get the address the pointer points to p := \u0026amp;i fmt.Printf(\u0026#34;Address of p=\u0026amp;i=%d: %p\\n\u0026#34;, *p, p) // get the address of pointer fmt.Printf(\u0026#34;Address of pointer p=\u0026amp;i=%d: %p\\n\u0026#34;, *p, \u0026amp;p) Output:\nAddress of i=32: 0xc00001c088 Address of p=\u0026amp;i=32: 0xc00001c088 Address of pointer p=\u0026amp;i=32: 0xc00000e030 The diagram below shows the relationship between variables and pointers in memory.\nPrint the address of a slice underlying array #Slices are values, so to print the address of a slice, you need to use the address operator \u0026amp;, just as you would for normal variables. But the verb %p also has a special meaning for slices. Quoting the documentation of the fmt package:\n%p\taddress of 0th element in base 16 notation, with leading 0x To print the address of the 0th element of the slice, which is equivalent to the address of the slice underlying array, you just need to use the %p format with the slice value argument. See the code below to compare the address of an example array, the address of a slice created by \u0026ldquo;slicing\u0026rdquo; the array, and the address of the 0th element of the slice (the address of the underlying array).\n// print address of array arr := [3]int{1, 2, 3} fmt.Printf(\u0026#34;Address of arr: %p\\n\u0026#34;, \u0026amp;arr) // print address of slice // \u0026#34;slicing\u0026#34; the array slice := arr[:] fmt.Printf(\u0026#34;Address of slice: %p\\n\u0026#34;, \u0026amp;slice) // print address of the slice underlying array fmt.Printf(\u0026#34;Address of the slice underlying array: %p\\n\u0026#34;, slice) // print address of 0th element of the slice fmt.Printf(\u0026#34;Address of 0th element of the slice: %p\\n\u0026#34;, \u0026amp;slice[0]) Output:\nAddress of arr: 0xc000014120 Address of slice: 0xc00000c030 Address of the slice underlying array: 0xc000014120 Address of 0th element of the slice: 0xc000014120 Print an address without leading 0x #To print the address without leading 0x, use the formatting pointer verb with the # flag: %#p.\n// print address of array arr := [3]int{1, 2, 3} fmt.Printf(\u0026#34;Address of arr: %#p\\n\u0026#34;, \u0026amp;arr) Output:\nAddress of arr: c000014120 Assign an address to a string #To get the address of a variable and assign it to string, use fmt.Sprintf() function:\narr := [3]int{1, 2, 3} addr := fmt.Sprintf(\u0026#34;%p\u0026#34;, \u0026amp;arr) fmt.Println(addr) Output:\n0xc0000b4000 ","date":"12 October 2021","permalink":"https://gosamples.dev/print-address/","section":"Tutorials","summary":"","title":"🧠 Print the memory address of a variable in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/array/","section":"Tags","summary":"","title":"Array"},{"content":"In Go, the length of a slice tells you how many elements it contains. It can be obtained using the len() function. The capacity is the size of the slice\u0026rsquo;s underlying array and can be obtained with the cap() function.\nDifference between arrays and slices #To better understand the difference between the capacity and length of a slice, first, you should know the differences between arrays and slices.\nArrays #An array is an indexed collection of a certain size with values of the same type, declared as: var name [size]type\nInitializing an array #var a [4]int // array with zero values var b [4]int = [4]int{0, 1, 2} // partially initialized array var c [4]int = [4]int{1, 2, 3, 4} // array initialization d := [...]int{5, 6, 7, 0} // ... - means that array size equals the number of elements in the array literal fmt.Printf(\u0026#34;a: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(a), cap(a), a) fmt.Printf(\u0026#34;b: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(b), cap(b), b) fmt.Printf(\u0026#34;c: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(c), cap(c), c) fmt.Printf(\u0026#34;d: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(d), cap(d), d) Output:\na: length: 4, capacity: 4, data: [0 0 0 0] b: length: 4, capacity: 4, data: [0 1 2 0] c: length: 4, capacity: 4, data: [1 2 3 4] d: length: 4, capacity: 4, data: [5 6 7 0] Properties of arrays # Arrays have a fixed size and cannot be resized. Slices can be resized. The type of the array includes its size. The [4]int array type is distinct from [5]int, and they cannot be compared. Initializing an array with var name [size]type creates a collection of size elements of type type and each of them is the zero value for the given type. Arrays are passed by value. It means that when you assign one array to another, you will make a new copy of its contents: var a [4]int = [4]int{1, 2, 3, 4} b := a a[1] = 999 fmt.Println(a) fmt.Println(b) Output:\n[1 999 3 4] [1 2 3 4] Slices #A slice declared as:\nvar name []type\nis a data structure describing a piece of an array with three properties:\nptr - a pointer to the underlying array len - length of the slice - number of elements in the slice cap - capacity of the slice - length of the underlying array, which is also the maximum length the slice can take (until it grows) A slice is not an array. It describes a section of the underlying array stored under the ptr pointer.\nInitializing a slice #var a []int // nil slice b := []int{0, 1, 2, 3} // slice initialized with specified array c := make([]int, 4) // slice of size 4 initialized with zero-valued array of size 4 d := make([]int, 4, 5) // slice of size 4 initialized with zero-valued array of size 5 fmt.Printf(\u0026#34;a: length: %d, capacity: %d, pointer to underlying array: %p, data: %v, is nil: %t\\n\u0026#34;, len(a), cap(a), a, a, a == nil) fmt.Printf(\u0026#34;b: length: %d, capacity: %d, pointer to underlying array: %p, data: %v, is nil: %t\\n\u0026#34;, len(b), cap(b), b, b, b == nil) fmt.Printf(\u0026#34;c: length: %d, capacity: %d, pointer to underlying array: %p, data: %v, is nil: %t\\n\u0026#34;, len(c), cap(c), c, c, c == nil) fmt.Printf(\u0026#34;d: length: %d, capacity: %d, pointer to underlying array: %p, data: %v, is nil: %t\\n\u0026#34;, len(d), cap(d), d, d, d == nil) Output:\na: length: 0, capacity: 0, pointer to underlying array: 0x0, data: [], is nil: true b: length: 4, capacity: 4, pointer to underlying array: 0xc00001e060, data: [0 1 2 3], is nil: false c: length: 4, capacity: 4, pointer to underlying array: 0xc00001e080, data: [0 0 0 0], is nil: false d: length: 4, capacity: 5, pointer to underlying array: 0xc000016180, data: [0 0 0 0], is nil: false As we see in the output, var a []int creates a nil slice - a slice that has the length and capacity equal to 0, and no underlying array. Initializing a slice with the specified array, i.e., b := []int{0, 1, 2, 3}, creates a new slice with capacity and length taken from the underlying array. A slice can also be initialized with the built-in make() function that takes the type of a slice as the first argument and the length as the second. The resulting slice has a capacity equals to the length, and the underlying array is initialized with zero values.\nThere is also an alternative version of the make() function with three arguments: the first is the type of a slice, the second is the length, and the third is the capacity. In this way, you can create a slice with a capacity greater than the length.\nProperties of slices # A slice is automatically resized when the append() function is called. Resizing here means that the append() adds new elements to the end of the slice, and if there is not sufficient capacity in the underlying array, a new array will be allocated. The append() function always returns a new, updated slice, so if you want to resize a slice s it is necessary to store the result in the same variable s. Slices are not comparable and simple equality comparison a == b is not possible. See how to compare slices. Initializing a slice with var name []type creates a nil slice that has length and capacity equal to 0 and no underlying array. See what is the difference between nil and empty slices. Just like arrays (and everything in Go), slices are passed by value. When you assign a slice to a new variable, the ptr, len, and cap are copied, including the ptr pointer that will point to the same underlying array. If you modify the copied slice, you modify the same shared array which makes all changes visible in the old and new slices: var a []int = []int{1, 2, 3, 4} b := a a[1] = 999 fmt.Println(a) fmt.Println(b) Output:\n[1 999 3 4] [1 999 3 4] Length and capacity #You already know that capacity is the size of the slice\u0026rsquo;s underlying array and length is the number of the slice elements, but what is the relationship between them? To understand this better, let\u0026rsquo;s analyze the re-slicing and appending operations.\nRe-slicing #Re-slicing is an operation that creates a new slice from an existing one or an array. To \u0026ldquo;slice\u0026rdquo; an array or \u0026ldquo;re-slice\u0026rdquo; an existing slice, use a half-open range with two indices separated by a colon:\nvar arr [4]int = [4]int{1, 2, 3, 4} a := arr[1:3] fmt.Printf(\u0026#34;a: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(a), cap(a), a) Output:\na: length: 2, capacity: 3, data: [2 3] We get the same results for the slice:\nvar s []int = []int{1, 2, 3, 4} a := s[1:3] fmt.Printf(\u0026#34;a: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(a), cap(a), a) Output:\na: length: 2, capacity: 3, data: [2 3] Re-slicing a slice or an array creates a new slice with length given by indices range and capacity equal to the number of elements in the underlying array from the index of the first element of the slice to the end of the array. See two more examples of re-slicing operation - for range without the first index s[:3], and without the last index s[3:]:\nb := s[:3] fmt.Printf(\u0026#34;b: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(b), cap(b), b) Output:\nb: length: 3, capacity: 4, data: [1 2 3] c := s[3:] fmt.Printf(\u0026#34;c: length: %d, capacity: %d, data: %v\\n\u0026#34;, len(c), cap(c), c) Output:\nc: length: 1, capacity: 1, data: [4] The append() function #Appending is one of the most important operations for slices. Since arrays in Go are immutable, only with the append() function we can get a variable-length data collection. However, as we know, underneath slices still use arrays. The example below shows what happens when the number of slice items exceeds its capacity.\nvar s []int for i := 0; i \u0026lt; 10; i++ { fmt.Printf(\u0026#34;length: %d, capacity: %d, address: %p\\n\u0026#34;, len(s), cap(s), s) s = append(s, i) } Output:\nlength: 0, capacity: 0, address: 0x0 length: 1, capacity: 1, address: 0xc00001c0a0 length: 2, capacity: 2, address: 0xc00001c0b0 length: 3, capacity: 4, address: 0xc00001e080 length: 4, capacity: 4, address: 0xc00001e080 length: 5, capacity: 8, address: 0xc000020140 length: 6, capacity: 8, address: 0xc000020140 length: 7, capacity: 8, address: 0xc000020140 length: 8, capacity: 8, address: 0xc000020140 length: 9, capacity: 16, address: 0xc000026200 As you can see in the output, every time the length of the slice is beyond its capacity (the length of the underlying array), the append() function expands the slice by allocating a new underlying array of twice its size and copying all of its elements there. Notice that the pointer to the underlying array changes with each change in capacity.\nConclusion #To understand the length and capacity of slices in Go, it is important to understand how slices work and what is the difference between slices and arrays. Slices are built on top of arrays to provide variable-length data collections. They consist of three elements - a pointer to the underlying array (underneath, slices use arrays as data storage), the length of the slice, and the capacity - the size of the underlying array. These 3 properties are copied when a slice value is passed, but the new pointer always points to the same shared array. The append() function makes slices expandable, creating a powerful and expressive data structure, one of the most used in Go.\n","date":"5 October 2021","permalink":"https://gosamples.dev/capacity-and-length/","section":"Tutorials","summary":"","title":"🏟️ Capacity and length of a slice in Go"},{"content":"When you try to assign a pointer of a literal, map value, or a function return value, your IDE or compiler prints the error: \u0026quot;cannot take address of XXX\u0026quot; where XXX is an element you want to assign. See the examples of invalid assignments and the compiler errors:\nGet address of value returned by a function #For\nt := \u0026amp;time.Now() // returns compiler error you get\ncannot take the address of time.Now() and for\nfooPtr := \u0026amp;foo() // returns compiler error you get\ncannot take the address of foo() Get address of map value #For\nm := map[int64]int64{ 1: 2, } a := \u0026amp;m[1] // returns compiler error you get\ncannot take the address of m[1] Get address of untyped constant #For\ni := \u0026amp;4 // returns compiler error you get\ncannot take the address of 4 Get address of typed constant #For\ni := \u0026amp;int64(4) // returns compiler error you get\ncannot take the address of int64(4) Why you cannot do that #To be able to get an address with the \u0026amp; operator, i.e., to perform the \u0026amp;x operation, x must be addressable. As The Go Programming Language Specification says:\nFor an operand x of type T, the address operation \u0026amp;x 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 \u0026amp;x does too.\nConstants, map index expressions, and values returned by a function are not addressable, so you cannot use the \u0026amp; operator on them. Practically speaking, the constants like 4, int64(4), or function return values like foo() have no address because there is no specific memory allocated for them; they can reside in processor registers. You can similarly think of map index values. A map is reallocated if the number of its elements grows above a certain threshold. If it were possible to retrieve the address of a map element, such a pointer could point to an invalid address after this reallocation. For this reason, taking the address of a map value is not allowed.\nAs a rule of thumb, you can think about \u0026amp; as an operator for taking the address of some existing variable with one exception: you can create a composite literal and use \u0026amp; to retrieve its address, for example, \u0026amp;T{}, \u0026amp;map[string]int64{\u0026quot;a\u0026quot;: 1} or \u0026amp;[]int{} are valid expressions.\nWhat you can do #In everyday coding, a common pattern, especially in writing tests, is to assign a constant to a struct pointer. Having a struct:\ntype A struct { Val *int } you cannot assign the constant in the way that seems the most simple:\na := A{ Val: \u0026amp;int(3), // compiler error: cannot take address of int(3) } However, there are other options. Let\u0026rsquo;s analyze them.\nThere is a lot of discussion about solving the problem of creating pointers to simple types as this becomes a real pain for many programmers. See the Github issue: #45624 in The Go Programming Language repository to follow the progress.\nUse a helper variable #The simplest and recommended way to assign a pointer to a value is to create a helper variable whose address can be taken.\nv := 3 a := A{ Val: \u0026amp;v, } Use a helper function #If you have multiple places where you want to assign a pointer to a constant, you can create a helper function that takes a concrete value and returns its address.\nfunc intPtr(i int) *int { return \u0026amp;i } ... v := 3 a := A{ Val: intPtr(v), } Use new() function #If you need to assign a zero value of a given type, you can use a built-in new() function to create a new variable and take its address.\na := A{ Val: new(int), } Use an anonymous function #This is equivalent to creating a helper function, but here we are creating an anonymous, single-line function.\na := A{ Val: func(i int) *int { return \u0026amp;i }(4), } Use a slice #The slice indexing operation is addressable, so you can initialize a new slice with a given value and take the address of its first element. However, this method is considered ugly and is not recommended.\na := A{ Val: \u0026amp;[]int{3}[0], } ","date":"4 October 2021","permalink":"https://gosamples.dev/cannot-take-address/","section":"Tutorials","summary":"","title":"🕵️ Solve 'cannot take address of XXX' error in Go"},{"content":"To convert a string to a bool in Go, use strconv.ParseBool() function from the strconv package. It takes one of the accepted string values: \u0026quot;1\u0026quot;, \u0026quot;t\u0026quot;, \u0026quot;T\u0026quot;, \u0026quot;TRUE\u0026quot;, \u0026quot;true\u0026quot;, \u0026quot;True\u0026quot;, \u0026quot;0\u0026quot;, \u0026quot;f\u0026quot;, \u0026quot;F\u0026quot;, \u0026quot;FALSE\u0026quot;, \u0026quot;false\u0026quot;, \u0026quot;False\u0026quot; and converts it to the equivalent boolean value: true or false. For any other string, the function returns an error.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;strconv\u0026#34; ) func main() { var boolValues = []string{ \u0026#34;1\u0026#34;, \u0026#34;t\u0026#34;, \u0026#34;T\u0026#34;, \u0026#34;TRUE\u0026#34;, \u0026#34;true\u0026#34;, \u0026#34;True\u0026#34;, \u0026#34;0\u0026#34;, \u0026#34;f\u0026#34;, \u0026#34;F\u0026#34;, \u0026#34;FALSE\u0026#34;, \u0026#34;false\u0026#34;, \u0026#34;False\u0026#34;, } for _, v := range boolValues { boolValue, err := strconv.ParseBool(v) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;%s: %t\\n\u0026#34;, v, boolValue) } } Output:\n1: true t: true T: true TRUE: true true: true True: true 0: false f: false F: false FALSE: false false: false False: false ","date":"30 September 2021","permalink":"https://gosamples.dev/string-to-bool/","section":"Tutorials","summary":"","title":"🔟 Convert string to bool in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/bool/","section":"Tags","summary":"","title":"Bool"},{"content":"To remove duplicate whitespaces from a string in Go, use strings.Fields() function that splits the string around one or more whitespace characters, then join the slice of substrings using strings.Join() with a single space separator. Alternatively, you can use a regular expression to find duplicate whitespace characters and replace them using the ReplaceAllString() method from the regexp package.\nRemove duplicate whitespaces using strings.Fields() function #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { s := \u0026#34;GOSAMPLES.dev is \\t \\r\\n the best Golang \\t\\t\\t\\t website in the \\n world!\u0026#34; res := strings.Join(strings.Fields(s), \u0026#34; \u0026#34;) fmt.Println(res) } In this method, we do two things:\nWe split the string around one or more whitespace characters using the strings.Fields() function. The whitespace characters are defined by unicode.IsSpace(), and include '\\t', '\\n', '\\r', ' ', among others. As a result, we get the slice: []string{\u0026#34;GOSAMPLES.dev\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;best\u0026#34;, \u0026#34;Golang\u0026#34;, \u0026#34;website\u0026#34;, \u0026#34;in\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;world!\u0026#34;} We join the slice of substrings using the strings.Join() function with a single space \u0026quot; \u0026quot; as a separator. This way, we construct the result string with all duplicate whitespaces removed. Remove duplicate whitespaces using regular expressions #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;regexp\u0026#34; ) func main() { s := \u0026#34;GOSAMPLES.dev is \\t \\r\\n the best Golang \\t\\t\\t\\t website in the \\n world!\u0026#34; pattern := regexp.MustCompile(`\\s+`) res := pattern.ReplaceAllString(s, \u0026#34; \u0026#34;) fmt.Println(res) } Using regular expressions, we can achieve the same effect as in the previous method. We define \\s+ pattern that matches at least one whitespace character ([ \\t\\r\\n\\f]) and then replace all occurrences of that expression with a single space, obtaining the string with duplicate whitespaces removed.\nBoth methods produce the same result, which is:\nGOSAMPLES.dev is the best Golang website in the world! ","date":"29 September 2021","permalink":"https://gosamples.dev/remove-duplicate-spaces/","section":"Tutorials","summary":"","title":"👯 Remove duplicate spaces from a string in Go"},{"content":"The broken pipe is a TCP/IP error occurring when you write to a stream where the other end (the peer) has closed the underlying connection. The first write to the closed connection causes the peer to reply with an RST packet indicating that the connection should be terminated immediately. The second write to the socket that has already received the RST causes the broken pipe error. To detect the broken pipe in Go, check if the error returned by the peer is equal to syscall.EPIPE. Usually, this error can be seen when the server crashes while the client is sending data to it.\nReproduce the broken pipe error #In the following example, we reproduce the broken pipe error by creating a server and client that do the following:\nthe server reads a single byte and then closes the connection the client sends three bytes with an interval of one second between them The server receives the first client byte and closes the connection. The next byte of the client sent to the closed connection causes the server to reply with an RST packet. The socket that received the RST will return the broken pipe error when more bytes are sent to it. This is what happens when the client sends the last byte to the server.\npackage main import ( \u0026#34;errors\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net\u0026#34; \u0026#34;os\u0026#34; \u0026#34;syscall\u0026#34; \u0026#34;time\u0026#34; ) func server() { listener, err := net.Listen(\u0026#34;tcp\u0026#34;, \u0026#34;:8080\u0026#34;) if err != nil { log.Fatal(err) } defer listener.Close() conn, err := listener.Accept() if err != nil { log.Fatal(\u0026#34;server\u0026#34;, err) os.Exit(1) } data := make([]byte, 1) if _, err := conn.Read(data); err != nil { log.Fatal(\u0026#34;server\u0026#34;, err) } conn.Close() } func client() { conn, err := net.Dial(\u0026#34;tcp\u0026#34;, \u0026#34;localhost:8080\u0026#34;) if err != nil { log.Fatal(\u0026#34;client\u0026#34;, err) } // write to make the connection closed on the server side if _, err := conn.Write([]byte(\u0026#34;a\u0026#34;)); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) } time.Sleep(1 * time.Second) // write to generate an RST packet if _, err := conn.Write([]byte(\u0026#34;b\u0026#34;)); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) } time.Sleep(1 * time.Second) // write to generate the broken pipe error if _, err := conn.Write([]byte(\u0026#34;c\u0026#34;)); err != nil { log.Printf(\u0026#34;client: %v\u0026#34;, err) if errors.Is(err, syscall.EPIPE) { log.Print(\u0026#34;This is broken pipe error\u0026#34;) } } } func main() { go server() time.Sleep(3 * time.Second) // wait for server to run client() } Output:\n2021/10/21 19:10:01 client: write tcp 127.0.0.1:50389-\u0026gt;127.0.0.1:8080: write: broken pipe 2021/10/21 19:10:01 This is broken pipe error Handle the broken pipe error #To handle the broken pipe, you need to check if the error returned from the other end of the connection is an instance of syscall.EPIPE. In the example above, we perform this check using the errors.Is() function and print the message \u0026quot;This is broken pipe error\u0026quot; if it occurs. The broken pipe can be seen on either the client or server side, depending on which one is trying to write to the closed connection. Typically there is no need to handle it in any special way since it is normal that a connection may be interrupted by either side of the communication. For example, you can ignore the error, log it or reconnect when it occurs.\nDifference between broken pipe and connection reset by peer #Usually, you get the broken pipe error when you write to the connection after the RST is sent, and when you read from the connection after the RST instead, you get the connection reset by peer error. Check our article about connection reset by peer error to better understand the difference between these two errors.\n","date":"17 September 2021","permalink":"https://gosamples.dev/broken-pipe/","section":"Tutorials","summary":"","title":"🪠 Handle 'broken pipe' error in Go"},{"content":"To convert a byte slice to io.Reader in Go, create a new bytes.Reader object using bytes.NewReader() function with the byte slice argument. The bytes.Reader type implements the io.Reader interface and can be used in any function that requires it as an argument.\npackage main import ( \u0026#34;bytes\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { data := []byte(\u0026#34;test byte slice\u0026#34;) // byte slice to bytes.Reader, which implements the io.Reader interface reader := bytes.NewReader(data) // read the data from reader buf := make([]byte, len(data)) if _, err := reader.Read(buf); err != nil { log.Fatal(err) } fmt.Println(string(buf)) } ","date":"15 September 2021","permalink":"https://gosamples.dev/byte-slice-to-io-reader/","section":"Tutorials","summary":"","title":"📚 Convert byte slice to io.Reader in Go"},{"content":"To create a single directory in Go, use the os.Mkdir() function. If you want to create a hierarchy of folders (nested directories), use os.MkdirAll(). Both functions require a path and permission bits of the folder as arguments.\nIn the examples below, we use the os.ModePerm constant as permission bits which is equivalent to 0777. For directories in Unix-like systems, it means that a user has rights to list, modify and search files in the directory.\nCreate a single directory #package main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { if err := os.Mkdir(\u0026#34;a\u0026#34;, os.ModePerm); err != nil { log.Fatal(err) } } The os.Mkdir() creates a new directory with the specified name, but cannot create subdirectories. For example, if you use os.Mkdir() with \u0026quot;a/b/c/d\u0026quot; as a name argument:\nos.Mkdir(\u0026#34;a/b/c/d\u0026#34;, os.ModePerm) you get the error:\nmkdir a/b/c/d: no such file or directory Create a hierarchy of directories (nested directories) #package main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { if err := os.MkdirAll(\u0026#34;a/b/c/d\u0026#34;, os.ModePerm); err != nil { log.Fatal(err) } } The os.MkdirAll() creates a given directory, along with any necessary parent folder. Use this function if you need to create a nested hierarchy of directories in your program.\n","date":"14 September 2021","permalink":"https://gosamples.dev/create-directory/","section":"Tutorials","summary":"","title":"📁 Create a directory in Go"},{"content":"To convert JSON data to a CSV file in Go, you need to create a new struct for JSON data, then decode the JSON file into an array of these structs, and finally save the data from this array as subsequent rows of the CSV file. The two main packages necessary to do this are encoding/json to decode the JSON data with the json.Decoder and encoding/csv to write the output CSV data using csv.Writer.\nSee also our examples of how to convert CSV to JSON and how to read CSV file or how to write data to a CSV file in Go.\nIn the example below, we use the data.json file:\n[ { \u0026#34;vegetable\u0026#34;: \u0026#34;carrot\u0026#34;, \u0026#34;fruit\u0026#34;: \u0026#34;banana\u0026#34;, \u0026#34;rank\u0026#34;: 1 }, { \u0026#34;vegetable\u0026#34;: \u0026#34;potato\u0026#34;, \u0026#34;fruit\u0026#34;: \u0026#34;strawberry\u0026#34;, \u0026#34;rank\u0026#34;: 2 } ] Code # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 package main import ( \u0026#34;encoding/csv\u0026#34; \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) type FruitAndVegetableRank struct { // 1. Create a new struct for storing read JSON objects Vegetable string `json:\u0026#34;vegetable\u0026#34;` Fruit string `json:\u0026#34;fruit\u0026#34;` Rank int64 `json:\u0026#34;rank\u0026#34;` } func convertJSONToCSV(source, destination string) error { // 2. Read the JSON file into the struct array sourceFile, err := os.Open(source) if err != nil { return err } // remember to close the file at the end of the function defer sourceFile.Close() var ranking []FruitAndVegetableRank if err := json.NewDecoder(sourceFile).Decode(\u0026amp;ranking); err != nil { return err } // 3. Create a new file to store CSV data outputFile, err := os.Create(destination) if err != nil { return err } defer outputFile.Close() // 4. Write the header of the CSV file and the successive rows by iterating through the JSON struct array writer := csv.NewWriter(outputFile) defer writer.Flush() header := []string{\u0026#34;vegetable\u0026#34;, \u0026#34;fruit\u0026#34;, \u0026#34;rank\u0026#34;} if err := writer.Write(header); err != nil { return err } for _, r := range ranking { var csvRow []string csvRow = append(csvRow, r.Vegetable, r.Fruit, fmt.Sprint(r.Rank)) if err := writer.Write(csvRow); err != nil { return err } } return nil } func main() { if err := convertJSONToCSV(\u0026#34;data.json\u0026#34;, \u0026#34;data.csv\u0026#34;); err != nil { log.Fatal(err) } } The contents of the output data.csv file:\nvegetable,fruit,rank carrot,banana,1 potato,strawberry,2 How it works #Create a new struct for storing read JSON objects # 11 12 13 14 15 16 type FruitAndVegetableRank struct { // 1. Create a new struct for storing read JSON objects Vegetable string `json:\u0026#34;vegetable\u0026#34;` Fruit string `json:\u0026#34;fruit\u0026#34;` Rank int64 `json:\u0026#34;rank\u0026#34;` } The first step of JSON to CSV conversion is to load the JSON data to a Go struct. So, we define a proper type, with the fields matching the data in the file and annotate them with JSON struct field tags to enable JSON decoding into that struct.\nRead the JSON file into the struct array # 19 20 21 22 23 24 25 26 27 28 29 30 // 2. Read the JSON file into the struct array sourceFile, err := os.Open(source) if err != nil { return err } // remember to close the file at the end of the function defer sourceFile.Close() var ranking []FruitAndVegetableRank if err := json.NewDecoder(sourceFile).Decode(\u0026amp;ranking); err != nil { return err } We can start processing our JSON file. We open it (remember to close the file to release resources back to the system, for example, using defer keyword) and then create a new json.Decoder with this file as an argument. Since json.NewDecoder(r io.Reader) requires io.Reader, we do not need to read the content of the file beforehand. If we were to use the json.Unmarshal() function, it would be necessary. With Decode() method, we read the JSON file and convert it to the slice of FruitAndVegetableRank objects.\nCreate a new file to store CSV data # 32 33 34 35 36 37 // 3. Create a new file to store CSV data outputFile, err := os.Create(destination) if err != nil { return err } defer outputFile.Close() The CSV data will be saved to a file, so in this step, we create a new destination file in a pretty standard way.\nWrite the header of the CSV file and the successive rows by iterating through the JSON struct array # 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 // 4. Write the header of the CSV file and the successive rows by iterating through the JSON struct array writer := csv.NewWriter(outputFile) defer writer.Flush() header := []string{\u0026#34;vegetable\u0026#34;, \u0026#34;fruit\u0026#34;, \u0026#34;rank\u0026#34;} if err := writer.Write(header); err != nil { return err } for _, r := range ranking { var csvRow []string csvRow = append(csvRow, r.Vegetable, r.Fruit, fmt.Sprint(r.Rank)) if err := writer.Write(csvRow); err != nil { return err } } As the last step, we create a new csv.Writer that writes the data in CSV format to the output file. Remember to call writer.Flush to ensure that all the buffered content is written before the function finishes. The writing process consists of iterating through the array of FruitAndVegetableRank objects and making a CSV row for each of them. Then, This row is saved using writer.Write() method. In the example, we also wrote the header row as the first line of the file.\n","date":"13 September 2021","permalink":"https://gosamples.dev/json-to-csv/","section":"Tutorials","summary":"","title":"📎 Convert JSON to CSV in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/csv/","section":"Tags","summary":"","title":"Csv"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/json/","section":"Tags","summary":"","title":"Json"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/compression/","section":"Tags","summary":"","title":"Compression"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/zip/","section":"Tags","summary":"","title":"Zip"},{"content":"To unzip a compressed archive in Go using the standard library, you need to use archive/zip package and open the file with the zip.OpenReader(name string) function. Extracting a ZIP file in this way involves iterating through all the archive files. For each of them, we create a new empty file or directory in the target path and then uncompress its byte content there.\nYou can also check our example on how to zip a file in Go\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 package main import ( \u0026#34;archive/zip\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;path/filepath\u0026#34; \u0026#34;strings\u0026#34; ) func unzipSource(source, destination string) error { // 1. Open the zip file reader, err := zip.OpenReader(source) if err != nil { return err } defer reader.Close() // 2. Get the absolute destination path destination, err = filepath.Abs(destination) if err != nil { return err } // 3. Iterate over zip files inside the archive and unzip each of them for _, f := range reader.File { err := unzipFile(f, destination) if err != nil { return err } } return nil } func unzipFile(f *zip.File, destination string) error { // 4. Check if file paths are not vulnerable to Zip Slip filePath := filepath.Join(destination, f.Name) if !strings.HasPrefix(filePath, filepath.Clean(destination)+string(os.PathSeparator)) { return fmt.Errorf(\u0026#34;invalid file path: %s\u0026#34;, filePath) } // 5. Create directory tree if f.FileInfo().IsDir() { if err := os.MkdirAll(filePath, os.ModePerm); err != nil { return err } return nil } if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } // 6. Create a destination file for unzipped content destinationFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer destinationFile.Close() // 7. Unzip the content of a file and copy it to the destination file zippedFile, err := f.Open() if err != nil { return err } defer zippedFile.Close() if _, err := io.Copy(destinationFile, zippedFile); err != nil { return err } return nil } func main() { err := unzipSource(\u0026#34;testFolder.zip\u0026#34;, \u0026#34;\u0026#34;) if err != nil { log.Fatal(err) } } How it works #Open the zip file # 14 15 16 17 18 19 // 1. Open the zip file reader, err := zip.OpenReader(source) if err != nil { return err } defer reader.Close() To unzip the file, first, open it with the zip.OpenReader(name string) function. As always, when working with files, remember to close it if you no longer need it, using the ReadCloser.Close() method in this case.\nGet the absolute destination path # 21 22 23 24 25 // 2. Get the absolute destination path destination, err = filepath.Abs(destination) if err != nil { return err } Convert our relative destination path to the absolute representation, which will be needed in the step of Zip Slip vulnerability checking.\nIterate over zip files inside the archive and unzip each of them # 27 28 29 30 31 32 33 // 3. Iterate over zip files inside the archive and unzip each of them for _, f := range reader.File { err := unzipFile(f, destination) if err != nil { return err } } The actual process of unzipping files in Go using archive/zip is to iterate through the files of the opened ZIP file and unpack each one individually to its final destination.\nCheck if file paths are not vulnerable to Zip Slip # 38 39 40 41 42 43 func unzipFile(f *zip.File, destination string) error { // 4. Check if file paths are not vulnerable to Zip Slip filePath := filepath.Join(destination, f.Name) if !strings.HasPrefix(filePath, filepath.Clean(destination)+string(os.PathSeparator)) { return fmt.Errorf(\u0026#34;invalid file path: %s\u0026#34;, filePath) } The first step of an individual file unzipping function is to check whether the path of this file does not make use of the Zip Slip vulnerability, which was discovered in 2018 and affected thousands of projects. With a specially crafted archive that holds directory traversal filenames, e.g., ../../evil.sh, an attacker can gain access to parts of the file system outside of the target folder in which the unzipped files should reside. The attacker can then overwrite executable files and other sensitive resources, causing significant damage to the victim machine.\nTo detect this vulnerability, prepare the target file path by combining the destination and the name of the file inside the ZIP archive. It can be done using filepath.Join() function. Then we check if this final file path contains our destination path as a prefix. If not, the file may be trying to access the part of the file system other than the destination and should be rejected.\nFor example, when we want to unzip our file into the /a/b/ directory:\nerr := unzipSource(\u0026#34;testFolder.zip\u0026#34;, \u0026#34;/a/b\u0026#34;) if err != nil { log.Fatal(err) } and in the archive there is a file with a name ../../../../evil.sh, then the output of\nfilepath.Join(\u0026#34;/a/b\u0026#34;, \u0026#34;../../../../evil.sh\u0026#34;) is\n/evil.sh In this way, the attacker can unzip the evil.sh file in the root directory /, which should not be allowed with our check.\nCreate a directory tree # 45 46 47 48 49 50 51 52 53 54 55 // 5. Create a directory tree if f.FileInfo().IsDir() { if err := os.MkdirAll(filePath, os.ModePerm); err != nil { return err } return nil } if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } For each file or directory in the ZIP archive, we need to create a corresponding directory in the destination path, so that the resulting directory tree of the extracted files matches the directory tree inside the ZIP. We use os.MkdirAll() function to do this. For directories, we create the corresponding folder in the destination path, and for files, we create the base directory of the file. Note that we return from the function when the file is a directory as only files need to be unzipped, which we will do in the next steps.\nCreate a destination file for unzipped content # 57 58 59 60 61 62 // 6. Create a destination file for unzipped content destinationFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer destinationFile.Close() Before uncompressing a ZIP archive file, we need to create a target file where the extracted content could be saved. Since the mode of this target file should match the mode of the file inside the archive, we use os.OpenFile() function, where we can set the mode as an argument.\nUnzip the content of a file and copy it to the destination file # 64 65 66 67 68 69 70 71 72 73 74 // 7. Unzip the content of a file and copy it to the destination file zippedFile, err := f.Open() if err != nil { return err } defer zippedFile.Close() if _, err := io.Copy(destinationFile, zippedFile); err != nil { return err } return nil In the last step, we open an individual ZIP file and copy its content to the file created in the previous step. Opening with zip.File.Open() gives access to the uncompressed data of the archive file while copying.\n","date":"9 September 2021","permalink":"https://gosamples.dev/unzip-file/","section":"Tutorials","summary":"","title":"🗄️ Unzip a file in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/const/","section":"Tags","summary":"","title":"Const"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/enum/","section":"Tags","summary":"","title":"Enum"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/iota/","section":"Tags","summary":"","title":"Iota"},{"content":"In Go, there is no enum data type known from languages such as C++, Java, or Python. However, this does not mean that enums cannot be created. If you declare constants of custom type and some helper methods, you get a structure very similar to enum in other programming languages.\nSee the example below to check how to declare enum in Go.\nIn the example, we use constants declaration with iota. Check our tutorial on how to use iota in Go.\npackage main import ( \u0026#34;fmt\u0026#34; ) type Season int const ( Spring Season = iota + 1 Summer Autumn Winter ) func (s Season) String() string { seasons := [...]string{\u0026#34;spring\u0026#34;, \u0026#34;summer\u0026#34;, \u0026#34;autumn\u0026#34;, \u0026#34;winter\u0026#34;} if s \u0026lt; Spring || s \u0026gt; Winter { return fmt.Sprintf(\u0026#34;Season(%d)\u0026#34;, int(s)) } return seasons[s-1] } func (s Season) IsValid() bool { switch s { case Spring, Summer, Autumn, Winter: return true } return false } func main() { mySeasons := []Season{Spring, Summer, Autumn, Winter, 6} for _, s := range mySeasons { fmt.Printf(\u0026#34;season: %s, is valid: %t\\n\u0026#34;, s, s.IsValid()) } } Output:\nseason: spring, is valid: true season: summer, is valid: true season: autumn, is valid: true season: winter, is valid: true season: Season(6), is valid: false How it works #Declare custom type and elements of our enum #type Season int const ( Spring Season = iota + 1 Summer Autumn Winter ) As a first step, we declare new integer type Season and create successive constant values using the iota keyword.\nWhy do we use int type instead of string? #Constants are usually used to compare to a variable, e.g.\nif Spring != season { // do something } and often we do not need their specific values, just the fact that the constant and the variable are different. In such a case comparing two int values is faster than comparing two strings. Constants of type int also take less memory space.\nWhy do we declare the custom type Season instead of using untyped constants? #A custom type protects against passing invalid values already at the compilation stage. If we declared seasons as untyped constants, the code below of assigning invalid season value 6 to the variable would execute without any error:\nvar d int = 6 season := Spring season = d When using Season type, to make this code run without any error, you need to explicitly convert the d variable, so it is not possible to do it by accident:\nvar d int = 6 season := Spring season = Season(d) Also, a custom type of enum makes the code cleaner. For example, declaring the function\nfunc foo(s Season) you immediately see that the function requires season as an argument, and in the case of\nfunc foo(s int) you only know that it needs an integer argument, without any semantic meaning. Thanks to the custom types we also can add methods to the enum elements like String() and IsValid().\nCreate String() method #func (s Season) String() string { seasons := [...]string{\u0026#34;spring\u0026#34;, \u0026#34;summer\u0026#34;, \u0026#34;autumn\u0026#34;, \u0026#34;winter\u0026#34;} if s \u0026lt; Spring || s \u0026gt; Winter { return fmt.Sprintf(\u0026#34;Season(%d)\u0026#34;, int(s)) } return seasons[s-1] } String() method adds the ability to print Season constants as a string rather than an int, so for the statement fmt.Println(Spring) we get spring instead of 1. For variables outside the range Spring..Winter, we print Season(X), where X is an integer value of the Season type variable.\nCreate IsValid() method #func (s Season) IsValid() bool { switch s { case Spring, Summer, Autumn, Winter: return true } return false } IsValid() is a helper method that validates whether the Season type variable is one of the values Spring, Summer, Autumn, or Winter. This function should always be called for user input, to verify that the user has not passed an invalid value of the enum.\nmain() function #func main() { mySeasons := []Season{Spring, Summer, Autumn, Winter, 6} for _, s := range mySeasons { fmt.Printf(\u0026#34;season: %s, is valid: %t\\n\u0026#34;, s, s.IsValid()) } } The main() function presents what you get when you use the String() and IsValid() methods for defined values of Season constants as well as values out of range.\n","date":"7 September 2021","permalink":"https://gosamples.dev/enum/","section":"Tutorials","summary":"","title":"🖐️ Declare enum in Go"},{"content":"The iota keyword within a constant declaration represents successive untyped integers starting from zero. When declaring constants, it often does not matter what their specific values are, but that they are distinct from each other, so instead of declaring constants in the form:\nconst ( Strawberry = \u0026#34;strawberry\u0026#34; Blueberry = \u0026#34;blueberry\u0026#34; Raspberry = \u0026#34;raspberry\u0026#34; ) we can declare them as integers:\nconst ( Strawberry = 1 Blueberry = 2 Raspberry = 3 ) and this declaration can be further simplified by the iota keyword:\nconst ( Strawberry = iota + 1 Blueberry // in Go, omitting the value of constant // within the constants list declaration is equivalent // to repeating the previous line value Raspberry ) The iota keyword starts a counter that increments for each line of the const declaration. Because its initial value is zero, in the example above, we declare the first constant as iota + 1. As a result, we receive 1 for Strawberry, 2 for Blueberry, and 3 for Raspberry.\nSkip iota value #If you want to skip an integer value in const declaration with iota, you can use the blank identifier _:\npackage main import \u0026#34;fmt\u0026#34; const ( Strawberry = iota + 1 Blueberry Raspberry _ Apple ) func main() { fmt.Println(Strawberry, Blueberry, Raspberry, Apple) } Advanced example #In addition to simply incrementing values, the iota keyword can also be used to compute more complex expressions. The example below, from Effective Go, shows the combination of the iota keyword, bitwise shift, and a custom type declaration with a String() method that formats the data differently depending on the value.\npackage main import \u0026#34;fmt\u0026#34; type ByteSize float64 const ( KB ByteSize = 1 \u0026lt;\u0026lt; (10 * (iota + 1)) MB GB ) func (b ByteSize) String() string { switch { case b \u0026gt;= GB: return fmt.Sprintf(\u0026#34;%.2fGB\u0026#34;, b/GB) case b \u0026gt;= MB: return fmt.Sprintf(\u0026#34;%.2fMB\u0026#34;, b/MB) case b \u0026gt;= KB: return fmt.Sprintf(\u0026#34;%.2fKB\u0026#34;, b/KB) } return fmt.Sprintf(\u0026#34;%.2fB\u0026#34;, b) } func main() { fmt.Println(1001*KB, 2.5*MB, 3.5*GB) fmt.Println(ByteSize(121000000)) } Output:\n1001.00KB 2.50MB 3.50GB 115.39MB ","date":"6 September 2021","permalink":"https://gosamples.dev/iota/","section":"Tutorials","summary":"","title":"🧐 iota in Go - how to use?"},{"content":"Slices in Go can be represented by 3 elements:\nptr - a pointer to the underlying array that contains data of the slice len - length, number of elements in the slice cap - capacity, number of elements in the underlying data array, starting from the element pointed by the ptr A nil slice declared as var s1 []string has no underlying data array - it points to nothing. An empty slice, declared as s2 := []string{} or s3 := make([]string, 0) points to an empty, non-nil array.\nSee also in detail what is the difference between length and capacity of slices\nSee the table to compare the properties of the nil and empty slices.\nptr len cap nil: []string 0 0 0 empty: []string{} \u0026lt;addr\u0026gt; 0 0 empty: make([]string, 0) \u0026lt;addr\u0026gt; 0 0 The \u0026lt;addr\u0026gt; is a non-zero address to an empty, non-nil array.\npackage main import \u0026#34;fmt\u0026#34; func main() { var s1 []string // nil s2 := []string{} // empty s3 := make([]string, 0) // empty, equivalent to s2 := []string{} fmt.Printf(\u0026#34;s1 is nil: %t, len: %d, cap: %d\\n\u0026#34;, s1 == nil, len(s1), cap(s1)) fmt.Printf(\u0026#34;s2 is nil: %t, len: %d, cap: %d\\n\u0026#34;, s2 == nil, len(s2), cap(s2)) fmt.Printf(\u0026#34;s3 is nil: %t, len: %d, cap: %d\\n\u0026#34;, s3 == nil, len(s3), cap(s3)) } Output:\ns1 is nil: true, len: 0, cap: 0 s2 is nil: false, len: 0, cap: 0 s3 is nil: false, len: 0, cap: 0 Empty and nil slices behave in the same way that is the built-in functions like len(), cap(), append(), and for .. range loop return the same results. So, since the nil slice declaration is simpler, you should prefer it to creating an empty slice. However, there are some cases when you may need the empty, non-nil slice. For instance, when you want to return an empty JSON array [] as an HTTP response, you should create the empty slice ([]string{} or make([]string, 0)) because if you use a nil slice, you will get a null JSON array after encoding:\npackage main import ( \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func main() { var s1 []string // nil s2 := []string{} // empty s3 := make([]string, 0) // empty, equivalent to s2 := []string{} s1JSON, err := json.Marshal(s1) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;s1 JSON: %s\\n\u0026#34;, string(s1JSON)) s2JSON, err := json.Marshal(s2) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;s2 JSON: %s\\n\u0026#34;, string(s2JSON)) s3JSON, err := json.Marshal(s3) if err != nil { log.Fatal(err) } fmt.Printf(\u0026#34;s3 JSON: %s\\n\u0026#34;, string(s3JSON)) } Output:\ns1 JSON: null s2 JSON: [] s3 JSON: [] ","date":"2 September 2021","permalink":"https://gosamples.dev/empty-vs-nil-slice/","section":"Tutorials","summary":"","title":"💡 Empty slice vs nil slice in Go"},{"content":"If you want your strings in Go to be printed in aligned columns, you need to add the padding, i.e., filling the string with whitespace characters at the beginning or end so that the output has a fixed number of characters. To do this, you can use special flags, like \u0026quot;%-10s\u0026quot;, added to format \u0026ldquo;verbs\u0026rdquo; when formatting text. You can also use an external package or the built-in text/tabwriter to print the data in aligned columns.\nPrint a string with padding using fmt #Using the built-in fmt.Printf() function, you can set the format of the printed data using so-called verbs such as \u0026quot;%s\u0026quot;. Moreover, there are several flags to improve the display of strings. One of them is the flag to add padding, which is the number specifying its size in the verb \u0026quot;%s\u0026quot;, between \u0026quot;%\u0026quot; and \u0026quot;s\u0026quot;. By default, the string is padded with spaces on the left (the text is right-justified). If you want right padding and left alignment, add the - flag before the padding size.\nExamples:\nformat description \u0026quot;%s\u0026quot; Standard string format \u0026quot;%20s\u0026quot; Pad string with the spaces on the left (right-justified string) \u0026quot;%-20s\u0026quot; Pad string with the spaces on the right (left-justified string) Left padding example #// left padding fmt.Printf(\u0026#34;+%s+\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, 45)) fmt.Printf(\u0026#34;| %20s | %20s |\\n\u0026#34;, \u0026#34;vegetables\u0026#34;, \u0026#34;fruits\u0026#34;) fmt.Printf(\u0026#34;|%s|\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, 45)) fmt.Printf(\u0026#34;| %20s | %20s |\\n\u0026#34;, \u0026#34;potato\u0026#34;, \u0026#34;strawberry\u0026#34;) fmt.Printf(\u0026#34;+%s+\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, 45)) Output:\n+---------------------------------------------+ | vegetables | fruits | |---------------------------------------------| | potato | strawberry | +---------------------------------------------+ Right padding example #// right padding fmt.Printf(\u0026#34;+%s+\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, 45)) fmt.Printf(\u0026#34;| %-20s | %-20s |\\n\u0026#34;, \u0026#34;vegetables\u0026#34;, \u0026#34;fruits\u0026#34;) fmt.Printf(\u0026#34;|%s|\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, 45)) fmt.Printf(\u0026#34;| %-20s | %-20s |\\n\u0026#34;, \u0026#34;potato\u0026#34;, \u0026#34;strawberry\u0026#34;) fmt.Printf(\u0026#34;+%s+\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, 45)) Output:\n+---------------------------------------------+ | vegetables | fruits | |---------------------------------------------| | potato | strawberry | +---------------------------------------------+ Variable padding size #But what if we would like to print a large table with columns of different widths, whose size would adapt to the length of the strings? In this case, the padding size will be variable, but that is not a problem for the fmt.Printf() function. The example below shows how to do this.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func printTable(table [][]string) { // get number of columns from the first table row columnLengths := make([]int, len(table[0])) for _, line := range table { for i, val := range line { if len(val) \u0026gt; columnLengths[i] { columnLengths[i] = len(val) } } } var lineLength int for _, c := range columnLengths { lineLength += c + 3 // +3 for 3 additional characters before and after each field: \u0026#34;| %s \u0026#34; } lineLength += 1 // +1 for the last \u0026#34;|\u0026#34; in the line for i, line := range table { if i == 0 { // table header fmt.Printf(\u0026#34;+%s+\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, lineLength-2)) // lineLength-2 because of \u0026#34;+\u0026#34; as first and last character } for j, val := range line { fmt.Printf(\u0026#34;| %-*s \u0026#34;, columnLengths[j], val) if j == len(line)-1 { fmt.Printf(\u0026#34;|\\n\u0026#34;) } } if i == 0 || i == len(table)-1 { // table header or last line fmt.Printf(\u0026#34;+%s+\\n\u0026#34;, strings.Repeat(\u0026#34;-\u0026#34;, lineLength-2)) // lineLength-2 because of \u0026#34;+\u0026#34; as first and last character } } } func main() { var table = [][]string{ {\u0026#34;vegetables\u0026#34;, \u0026#34;fruits\u0026#34;, \u0026#34;rank\u0026#34;}, {\u0026#34;potato\u0026#34;, \u0026#34;strawberry\u0026#34;, \u0026#34;1\u0026#34;}, {\u0026#34;lettuce\u0026#34;, \u0026#34;raspberry\u0026#34;, \u0026#34;2\u0026#34;}, {\u0026#34;carrot\u0026#34;, \u0026#34;apple\u0026#34;, \u0026#34;3\u0026#34;}, {\u0026#34;broccoli\u0026#34;, \u0026#34;pomegranate\u0026#34;, \u0026#34;4\u0026#34;}, } printTable(table) } Output:\n+---------------------------------+ | vegetables | fruits | rank | +---------------------------------+ | potato | strawberry | 1 | | lettuce | raspberry | 2 | | carrot | apple | 3 | | broccoli | pomegranate | 4 | +---------------------------------+ Most of the code is used to calculate the number of characters to print, and you will have no trouble understanding it if you carefully follow it. What interests us the most is the line:\nfmt.Printf(\u0026#34;| %-*s \u0026#34;, columnLengths[j], val) An asterisk * in the format specifies that the padding size should be given as an argument to the fmt.Printf() function. In this case, the padding is columnLengths[j].\nRearrange the arguments #It is also possible to rearrange the arguments in the format string. The example below shows that by adding numeric values in square brackets in front of the formatting placeholders, we can control the order in which each argument occurs.\nfmt.Printf(\u0026#34;| %-[2]*[1]s \u0026#34;, val, columnLengths[j]) The [n] notation is especially useful if we have repeating values in the string format. In such a situation they can only be given as an argument once:\nfmt.Printf(\u0026#34;I\u0026#39;m a %[1]s, a great %[1]s\\n\u0026#34;, \u0026#34;programmer\u0026#34;) Summarized examples with the variable size padding:\nformat description \u0026quot;%s\u0026quot; Standard string format \u0026quot;%*s\u0026quot; Pad string with a variable number of spaces on the left (right-justified string) \u0026quot;%-*s\u0026quot; Pad string with a variable number of spaces on the right (left-justified string) \u0026quot;%-[2]*[1]s\u0026quot; As above but the first argument is the string, and the second, the padding size Print text in aligned columns using text/tabwriter #The Go standard library also includes a useful text/tabwriter package that creates properly aligned tables from strings separated by \\t characters. This type of formatting is particularly useful for creating command-line applications that print tabular data. In the example below, we initialize tabwriter.Writer by setting output to the standard output os.Stdout, \\t as the padding character and 4 as the width of the tab character. For printing, the line cells should be concatenated into a single string separated by tabs. We do this using the strings.Join() function. The tabwriter.Writer requires every column cell to be tab-terminated, so we also add the \\t for the last cell in the row.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;text/tabwriter\u0026#34; ) func printTable(table [][]string) { writer := tabwriter.NewWriter(os.Stdout, 0, 4, 0, \u0026#39;\\t\u0026#39;, 0) for _, line := range table { fmt.Fprintln(writer, strings.Join(line, \u0026#34;\\t\u0026#34;)+\u0026#34;\\t\u0026#34;) } writer.Flush() } func main() { var table = [][]string{ {\u0026#34;vegetables\u0026#34;, \u0026#34;fruits\u0026#34;, \u0026#34;rank\u0026#34;}, {\u0026#34;potato\u0026#34;, \u0026#34;strawberry\u0026#34;, \u0026#34;1\u0026#34;}, {\u0026#34;lettuce\u0026#34;, \u0026#34;raspberry\u0026#34;, \u0026#34;2\u0026#34;}, {\u0026#34;carrot\u0026#34;, \u0026#34;apple\u0026#34;, \u0026#34;3\u0026#34;}, {\u0026#34;broccoli\u0026#34;, \u0026#34;pomegranate\u0026#34;, \u0026#34;4\u0026#34;}, } printTable(table) } Output:\nvegetables fruits rank potato strawberry 1 lettuce raspberry 2 carrot apple 3 broccoli pomegranate 4 ","date":"27 August 2021","permalink":"https://gosamples.dev/string-padding/","section":"Tutorials","summary":"","title":"📰 String padding in Go"},{"content":"To zip a file or a directory in Go using the standard library, use zip.Writer type from the archive/zip package. Creating a compressed archive using this method involves going through all the files you want to include, generating a local file header for each one, and writing its contents to the resulting ZIP file.\nCheck also our example on how to unzip a file in Go\npackage main import ( \u0026#34;archive/zip\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;path/filepath\u0026#34; ) func zipSource(source, target string) error { // 1. Create a ZIP file and zip.Writer f, err := os.Create(target) if err != nil { return err } defer f.Close() writer := zip.NewWriter(f) defer writer.Close() // 2. Go through all the files of the source return filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err } // 3. Create a local file header header, err := zip.FileInfoHeader(info) if err != nil { return err } // set compression header.Method = zip.Deflate // 4. Set relative path of a file as the header name header.Name, err = filepath.Rel(filepath.Dir(source), path) if err != nil { return err } if info.IsDir() { header.Name += \u0026#34;/\u0026#34; } // 5. Create writer for the file header and save content of the file headerWriter, err := writer.CreateHeader(header) if err != nil { return err } if info.IsDir() { return nil } f, err := os.Open(path) if err != nil { return err } defer f.Close() _, err = io.Copy(headerWriter, f) return err }) } func main() { if err := zipSource(\u0026#34;testFolder\u0026#34;, \u0026#34;testFolder.zip\u0026#34;); err != nil { log.Fatal(err) } if err := zipSource(\u0026#34;testFolder/1/1.1/1.1.txt\u0026#34;, \u0026#34;1.1.zip\u0026#34;); err != nil { log.Fatal(err) } } In the example above, we use a sample directory testFolder:\ntestFolder ├── 1 │ └── 1.1 │ └── 1.1.txt ├── 2 └── test.txt The zipSource(source, target string) function does the following:\nCreate a ZIP file and zip.Writer #// 1. Create a ZIP file and zip.Writer f, err := os.Create(target) if err != nil { return err } defer f.Close() writer := zip.NewWriter(f) defer writer.Close() In the first step, we need to create a ZIP file and initialize zip.Writer that writes the compressed data to the file. Notice that we defer closing the file and the writer to the end of the zipSource() function.\nGo through all the files of the source #// 2. Go through all the files of the source return filepath.Walk(source, func(path string, info os.FileInfo, err error) error { ... }) We want the zipSource() function to work on both a single file and a folder, so we need to walk through each file of the source path using the filepath.Walk() function.\nCreate a local file header #// 3. Create a local file header header, err := zip.FileInfoHeader(info) if err != nil { return err } // set compression header.Method = zip.Deflate For each file in the archive, we need to create a local file header using the FileInfoHeader() function. The generated header does not have the compression method set, so we explicitly set it to zip.Deflate.\nSet the relative path of a file as the header name #// 4. Set relative path of a file as the header name header.Name, err = filepath.Rel(filepath.Dir(source), path) if err != nil { return err } if info.IsDir() { header.Name += \u0026#34;/\u0026#34; } In the previous step, we created a file header using FileInfoHeader(fi fs.FileInfo) function with the name from fs.FileInfo argument. However, this is just a base name, so we need to modify it to preserve the directory structure in the generated ZIP. We do this by calculating the relative path from the source path directory to the specified file path using filepath.Dir() and filepath.Rel() functions. For example, compressing the /a/b/c directory with /a/b/c/d/test.txt file gives us:\nfilepath.Rel(filepath.Dir(\u0026#34;/a/b/c\u0026#34;), \u0026#34;/a/b/c/d/test.txt\u0026#34;) which is equivalent to:\nfilepath.Rel(\u0026#34;/a/b/\u0026#34;, \u0026#34;/a/b/c/d/test.txt\u0026#34;) As a result, we get the relative path:\n\u0026#34;c/d/test.txt\u0026#34; Also, if the file is a directory, it should be marked with a trailing slash.\nCreate writer for the file header and save content of the file #// 5. Create a writer for the file header and save the content of the file headerWriter, err := writer.CreateHeader(header) if err != nil { return err } if info.IsDir() { return nil } f, err := os.Open(path) if err != nil { return err } defer f.Close() _, err = io.Copy(headerWriter, f) return err The last step is to create a writer for the specified file data based on the header. The data is transferred to the ZIP file using the io.Copy() function. Files that are directories should not be copied to avoid an error.\n","date":"25 August 2021","permalink":"https://gosamples.dev/zip-file/","section":"Tutorials","summary":"","title":"🗜️ Zip a file in Go"},{"content":"Slices in Go are not comparable, so a simple equality comparison a == b is not possible. To check if two slices are equal, write a custom function that compares their lengths and corresponding elements in a loop.\nNote that comparing two arrays is possible:\na := [2]string{\u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} b := [2]string{\u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} fmt.Printf(\u0026#34;slices equal: %t\\n\u0026#34;, a == b) package main import \u0026#34;fmt\u0026#34; func stringSlicesEqual(a, b []string) bool { if len(a) != len(b) { return false } for i, v := range a { if v != b[i] { return false } } return true } func main() { a := []string{\u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} b := []string{\u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} fmt.Printf(\u0026#34;slices equal: %t\\n\u0026#34;, stringSlicesEqual(a, b)) b = append(b, \u0026#34;test\u0026#34;) fmt.Printf(\u0026#34;slices equal: %t\\n\u0026#34;, stringSlicesEqual(a, b)) } Output:\nslices equal: true slices equal: false You can also use the reflect.DeepEqual() function that compares two values recursively, which means it traverses and checks the equality of the corresponding data values at each level. However, this solution is much slower and less safe than comparing values in a loop. A general rule of thumb when using the reflect package is: it should be used with care and avoided unless strictly necessary.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;reflect\u0026#34; ) func main() { a := []string{\u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} b := []string{\u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} fmt.Printf(\u0026#34;slices equal: %t\\n\u0026#34;, reflect.DeepEqual(a, b)) b = append(b, \u0026#34;test\u0026#34;) fmt.Printf(\u0026#34;slices equal: %t\\n\u0026#34;, reflect.DeepEqual(a, b)) } Output:\nslices equal: true slices equal: false ","date":"24 August 2021","permalink":"https://gosamples.dev/compare-slices/","section":"Tutorials","summary":"","title":"🍕 Compare two slices in Go"},{"content":"When you write a program that processes large amounts of data, or you test a program that creates files, you often need the ability to create temporary files that allow you to store your data for a short time without cluttering your project\u0026rsquo;s disk space. In Go, you can create a temporary file with os.CreateTemp() function and a temporary directory with os.MkdirTemp() function.\nos.CreateTemp() and os.MkdirTemp() are available since Go 1.17. For older versions you can use ioutil.TempFile() and ioutil.TempDir().\nCreate a temporary file #package main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { // create and open a temporary file f, err := os.CreateTemp(\u0026#34;\u0026#34;, \u0026#34;tmpfile-\u0026#34;) // in Go version older than 1.17 you can use ioutil.TempFile if err != nil { log.Fatal(err) } // close and remove the temporary file at the end of the program defer f.Close() defer os.Remove(f.Name()) // write data to the temporary file data := []byte(\u0026#34;abc abc abc\u0026#34;) if _, err := f.Write(data); err != nil { log.Fatal(err) } } The function func CreateTemp(dir, pattern string) (*File, error) has two parameters:\ndir which is a directory where a temporary file should be created. If left empty, the default directory for temporary files (for a given OS) is used. pattern that is used to generate names of temporary files. The name is created by appending a random string to the end of the pattern. In this way, in the example, we get names such as tmpfile-483140887. You can also use * to indicate where the random string should be placed. Giving tmpfile-*.txt you get, for example, tmpfile-483140887.txt. If you don\u0026rsquo;t use the temporary file anymore, it is a good practice to remove it using os.Remove().\nCreate a temporary directory #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { // create a temporary directory name, err := os.MkdirTemp(\u0026#34;\u0026#34;, \u0026#34;dir\u0026#34;) // in Go version older than 1.17 you can use ioutil.TempDir if err != nil { log.Fatal(err) } // remove the temporary directory at the end of the program defer os.RemoveAll(name) // print path of the directory fmt.Println(name) } Parameters of the func MkdirTemp(dir, pattern string) (string, error) function work the same way as in the case of os.CreateTemp(). As before, after you finish working with the temporary folder, you should remember to delete it, for example, via os.RemoveAll.\n","date":"23 August 2021","permalink":"https://gosamples.dev/temp-file/","section":"Tutorials","summary":"","title":"⌛ Temporary file in Go - how to create?"},{"content":"Standard fmt.Print() does not print variable names of Go structs, but it does not mean you cannot do that. To print struct variables in Go, you can use the following methods:\nUse fmt.Printf() with format \u0026ldquo;verbs\u0026rdquo; %+v or %#v. Convert the struct to JSON and print the output. Use external packages to pretty-print structs, for example, go-spew. See the example below and compare these three options.\npackage main import ( \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;github.com/davecgh/go-spew/spew\u0026#34; ) type Fruit struct { Name string color string Similar *Fruit } func main() { strawberry := Fruit{ Name: \u0026#34;strawberry\u0026#34;, color: \u0026#34;red\u0026#34;, Similar: nil, } raspberry := Fruit{ Name: \u0026#34;raspberry\u0026#34;, color: \u0026#34;pink\u0026#34;, Similar: \u0026amp;strawberry, } // fmt.Printf with format verbs fmt.Printf(\u0026#34;fmt.Printf with format verbs\\n\u0026#34;) fmt.Printf(\u0026#34;%+v\\n%#v\\n\u0026#34;, raspberry, raspberry) // json encoding fmt.Printf(\u0026#34;---\\njson encoding\\n\u0026#34;) jsonData, err := json.Marshal(\u0026amp;raspberry) if err != nil { log.Fatal(err) } fmt.Println(string(jsonData)) // go-spew fmt.Printf(\u0026#34;---\\ngo-spew\\n\u0026#34;) spew.Dump(raspberry) } Output:\nfmt.Printf with format verbs {Name:raspberry color:pink Similar:0xc000070390} main.Fruit{Name:\u0026#34;raspberry\u0026#34;, color:\u0026#34;pink\u0026#34;, Similar:(*main.Fruit)(0xc000070390)} --- json encoding {\u0026#34;Name\u0026#34;:\u0026#34;raspberry\u0026#34;,\u0026#34;Similar\u0026#34;:{\u0026#34;Name\u0026#34;:\u0026#34;strawberry\u0026#34;,\u0026#34;Similar\u0026#34;:null}} --- go-spew (main.Fruit) { Name: (string) (len=9) \u0026#34;raspberry\u0026#34;, color: (string) (len=4) \u0026#34;pink\u0026#34;, Similar: (*main.Fruit)(0xc000070390)({ Name: (string) (len=10) \u0026#34;strawberry\u0026#34;, color: (string) (len=3) \u0026#34;red\u0026#34;, Similar: (*main.Fruit)(\u0026lt;nil\u0026gt;) }) } Note the differences:\nfmt.Printf() prints only field values, which in the case of a pointer, it is the memory address of the variable it points to. Encoding to JSON requires all struct fields to be exported (the first letter capitalized). Otherwise, unexported fields such as color will not appear in the resulting JSON. Package go-spew prints detailed information about the struct, but it is an external dependency that needs to be imported. Depending on your use case, you should choose the method that suits you best.\n","date":"20 August 2021","permalink":"https://gosamples.dev/print-struct-variables/","section":"Tutorials","summary":"","title":"👣 Print struct variables in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/go-spew/","section":"Tags","summary":"","title":"Go-Spew"},{"content":"Context Deadline Exceeded is an error occurring in Go when a context of an HTTP request has a deadline or a timeout set, i.e., the time after which the request should abort. This error is returned if the time of a server response is greater than the set timeout. Setting timeouts on requests is a good practice in a production environment to ensure that you always get a response (or error) in a finite time.\nContext deadline exceeded example # package main import ( \u0026#34;context\u0026#34; \u0026#34;errors\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;os\u0026#34; \u0026#34;time\u0026#34; ) func slowServer(w http.ResponseWriter, r *http.Request) { time.Sleep(10 * time.Second) w.Write([]byte(\u0026#34;Hello world!\u0026#34;)) } func call() error { client := \u0026amp;http.Client{} req, err := http.NewRequest(http.MethodGet, \u0026#34;http://localhost:8080\u0026#34;, nil) if err != nil { return err } ctx, cancel := context.WithTimeout(req.Context(), 1*time.Second) defer cancel() req = req.WithContext(ctx) _, err = client.Do(req) return err } func main() { // run slow server go func() { http.HandleFunc(\u0026#34;/\u0026#34;, slowServer) if err := http.ListenAndServe(\u0026#34;:8080\u0026#34;, nil); err != nil { log.Fatal(err) } }() time.Sleep(1 * time.Second) // wait for server to run // call server err := call() if errors.Is(err, context.DeadlineExceeded) { log.Println(\u0026#34;ContextDeadlineExceeded: true\u0026#34;) } if os.IsTimeout(err) { log.Println(\u0026#34;IsTimeoutError: true\u0026#34;) } if err != nil { log.Fatal(err) } } Output:\n2021/08/19 06:39:09 ContextDeadlineExceeded: true 2021/08/19 06:39:09 IsTimeoutError: true 2021/08/19 06:39:09 Get \u0026#34;http://localhost:8080\u0026#34;: context deadline exceeded exit status 1 In the example above, we:\nrun our slow server, whose task is to return a response after 10 seconds create a new request in the call() function, which will be sent to the server set a timeout of 1 second on this request, i.e., the value of time after the waiting for the server response is interrupted send the request to the server Since a timeout for this request is set to 1 second and the server responds after 10 seconds, the HTTP client returns an error.\nHandle Context deadline exceeded error #An HTTP client returns the context.DeadlineExceeded error when the set timeout is exceeded. This error can also be handled with the more general os.IsTimeout() function that checks if the error is known to report that a timeout occurred.\nContext deadline exceeded (Client.Timeout exceeded while awaiting headers) example #The timeout can be set not only at the level of a single HTTP request but also at the level of the entire HTTP client. In this case, each request made by such a client has the same timeout value. See the example of a call() function using the client timeout option:\nfunc call() error { client := \u0026amp;http.Client{Timeout: 1 * time.Second} _, err := client.Get(\u0026#34;http://localhost:8080\u0026#34;) return err } Output:\n2021/08/19 07:35:14 IsTimeoutError: true 2021/08/19 07:35:14 Get \u0026#34;http://localhost:8080\u0026#34;: context deadline exceeded (Client.Timeout exceeded while awaiting headers) exit status 1 In this case, we get the context deadline exceeded (Client.Timeout exceeded while awaiting headers) error. Note that this is not an instance of context.DeadlineExceeded error.\n","date":"19 August 2021","permalink":"https://gosamples.dev/context-deadline-exceeded/","section":"Tutorials","summary":"","title":"📡 Handle Context Deadline Exceeded error in Go"},{"content":"To convert CSV data to JSON in Go, you should follow these steps:\nCreate a struct for storing CSV lines and annotate it with JSON struct field tags. Read CSV file using csv.Reader. Assign successive lines of raw CSV data to instances of the created struct. Convert an array of structs to JSON using marshaling functions from the encoding/json package. In the example below, we use data.csv file:\nvegetables,fruits,rank carrot,banana,1 potato,strawberry,2 See also our examples of how to convert JSON to CSV and how to read CSV file or how to write data to a CSV file in Go\npackage main import ( \u0026#34;encoding/csv\u0026#34; \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;strconv\u0026#34; ) type ShoppingRecord struct { // 1. Create a struct for storing CSV lines and annotate it with JSON struct field tags Vegetable string `json:\u0026#34;vegetable\u0026#34;` Fruit string `json:\u0026#34;fruit\u0026#34;` Rank int `json:\u0026#34;rank\u0026#34;` } func createShoppingList(data [][]string) []ShoppingRecord { // convert csv lines to array of structs var shoppingList []ShoppingRecord for i, line := range data { if i \u0026gt; 0 { // omit header line var rec ShoppingRecord for j, field := range line { if j == 0 { rec.Vegetable = field } else if j == 1 { rec.Fruit = field } else if j == 2 { var err error rec.Rank, err = strconv.Atoi(field) if err != nil { continue } } } shoppingList = append(shoppingList, rec) } } return shoppingList } func main() { // open file f, err := os.Open(\u0026#34;data.csv\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file at the end of the program defer f.Close() // 2. Read CSV file using csv.Reader csvReader := csv.NewReader(f) data, err := csvReader.ReadAll() if err != nil { log.Fatal(err) } // 3. Assign successive lines of raw CSV data to fields of the created structs shoppingList := createShoppingList(data) // 4. Convert an array of structs to JSON using marshaling functions from the encoding/json package jsonData, err := json.MarshalIndent(shoppingList, \u0026#34;\u0026#34;, \u0026#34; \u0026#34;) if err != nil { log.Fatal(err) } fmt.Println(string(jsonData)) } Output:\n[ { \u0026#34;vegetable\u0026#34;: \u0026#34;carrot\u0026#34;, \u0026#34;fruit\u0026#34;: \u0026#34;banana\u0026#34;, \u0026#34;rank\u0026#34;: 1 }, { \u0026#34;vegetable\u0026#34;: \u0026#34;potato\u0026#34;, \u0026#34;fruit\u0026#34;: \u0026#34;strawberry\u0026#34;, \u0026#34;rank\u0026#34;: 2 } ] ","date":"17 August 2021","permalink":"https://gosamples.dev/csv-to-json/","section":"Tutorials","summary":"","title":"🔄 Convert CSV to JSON in Go"},{"content":"To easily read and parse CSV (or TSV) files in Go, you can use two methods of encoding/csv package:\ncsv.Reader.ReadAll() to read and parse the entire file at once. Note however that a very large file may not fit into the memory. csv.Reader.Read() to read the CSV file line by line. See also our example of how to write data to a CSV file in Go\nIn the examples below, we use data.csv file:\nvegetables,fruits carrot,banana potato,strawberry Read the entire CSV file at once #In this example, we open the CSV file, initialize csv.Reader and read all the data into a [][]string slice where the first index is the file\u0026rsquo;s line number and the second is an index of the comma-separated value in this line. We can do something with these data, for example, convert to an array of structs.\npackage main import ( \u0026#34;encoding/csv\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) type ShoppingRecord struct { Vegetable string Fruit string } func createShoppingList(data [][]string) []ShoppingRecord { var shoppingList []ShoppingRecord for i, line := range data { if i \u0026gt; 0 { // omit header line var rec ShoppingRecord for j, field := range line { if j == 0 { rec.Vegetable = field } else if j == 1 { rec.Fruit = field } } shoppingList = append(shoppingList, rec) } } return shoppingList } func main() { // open file f, err := os.Open(\u0026#34;data.csv\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file at the end of the program defer f.Close() // read csv values using csv.Reader csvReader := csv.NewReader(f) data, err := csvReader.ReadAll() if err != nil { log.Fatal(err) } // convert records to array of structs shoppingList := createShoppingList(data) // print the array fmt.Printf(\u0026#34;%+v\\n\u0026#34;, shoppingList) } Output:\n[{Vegetable:carrot Fruit:banana} {Vegetable:potato Fruit:strawberry}] Read a CSV file line by line #Reading line by line is similar to reading the whole file at once, but in this case, we use csv.Reader.Read() method to read the next line of data in the infinite loop. This loop is exited when no more data are available, i.e., io.EOF error occurs.\npackage main import ( \u0026#34;encoding/csv\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { // open file f, err := os.Open(\u0026#34;data.csv\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file at the end of the program defer f.Close() // read csv values using csv.Reader csvReader := csv.NewReader(f) for { rec, err := csvReader.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } // do something with read line fmt.Printf(\u0026#34;%+v\\n\u0026#34;, rec) } } Output:\n[vegetables fruits] [carrot banana] [potato strawberry] Use a non-default field delimiter and read a TSV file #The standard separator for csv.Reader is the comma, but it\u0026rsquo;s easy to change it to any rune. For instance, you can change it to the tab character \\t, and in this way, you get the TSV reader:\ncsvReader.Comma = \u0026#39;\\t\u0026#39; ","date":"16 August 2021","permalink":"https://gosamples.dev/read-csv/","section":"Tutorials","summary":"","title":"🗒️ Read a CSV file in Go"},{"content":"An email address in Golang can be validated using the standard library function mail.ParseAddress. This function parses an RFC 5322 address, but by using it appropriately, we can also check if a string is a valid email address and get it from the \u0026quot;name \u0026lt;local-part@domain\u0026gt;\u0026quot; format.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/mail\u0026#34; ) func validMailAddress(address string) (string, bool) { addr, err := mail.ParseAddress(address) if err != nil { return \u0026#34;\u0026#34;, false } return addr.Address, true } var addresses = []string{ \u0026#34;foo@gmail.com\u0026#34;, \u0026#34;Gopher \u0026lt;from@example.com\u0026gt;\u0026#34;, \u0026#34;example\u0026#34;, } func main() { for _, a := range addresses { if addr, ok := validMailAddress(a); ok { fmt.Printf(\u0026#34;value: %-30s valid email: %-10t address: %s\\n\u0026#34;, a, ok, addr) } else { fmt.Printf(\u0026#34;value: %-30s valid email: %-10t\\n\u0026#34;, a, ok) } } } Output:\nvalue: foo@gmail.com valid email: true address: foo@gmail.com value: Gopher \u0026lt;from@example.com\u0026gt; valid email: true address: from@example.com value: example valid email: false ","date":"13 August 2021","permalink":"https://gosamples.dev/validate-email/","section":"Tutorials","summary":"","title":"📨 Validate an email address in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/mail/","section":"Tags","summary":"","title":"Mail"},{"content":"To convert interface to string in Go, use fmt.Sprint function, which gets the default string representation of any value. If you want to format an interface using a non-default format, use fmt.Sprintf with %v verb.\nfmt.Sprint(val) is equivalent to fmt.Sprintf(\u0026quot;%v\u0026quot;, val)\npackage main import \u0026#34;fmt\u0026#34; var testValues = []interface{}{ \u0026#34;test\u0026#34;, 2, 3.2, []int{1, 2, 3, 4, 5}, struct { A string B int }{ A: \u0026#34;A\u0026#34;, B: 5, }, } func main() { // method 1 fmt.Println(\u0026#34;METHOD 1\u0026#34;) for _, v := range testValues { valStr := fmt.Sprint(v) fmt.Println(valStr) } // method 2 fmt.Printf(\u0026#34;\\nMETHOD 2\\n\u0026#34;) for _, v := range testValues { valStr := fmt.Sprintf(\u0026#34;value: %v\u0026#34;, v) fmt.Println(valStr) } } Output:\nMETHOD 1 test 2 3.2 [1 2 3 4 5] {A 5} METHOD 2 value: test value: 2 value: 3.2 value: [1 2 3 4 5] value: {A 5} Alternatively, you can use the %+v verb to add field names to struct representation:\ntest 2 3.2 [1 2 3 4 5] {A:A B:5} or use %#v to format value in the Go-syntax style:\n\u0026#34;test\u0026#34; 2 3.2 []int{1, 2, 3, 4, 5} struct { A string; B int }{A:\u0026#34;A\u0026#34;, B:5} ","date":"12 August 2021","permalink":"https://gosamples.dev/interface-to-string/","section":"Tutorials","summary":"","title":"⚙️ Convert interface to string in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/interface/","section":"Tags","summary":"","title":"Interface"},{"content":"Measuring the execution time of a given code block in Go consists of two steps that need to be done before and after a measured function. Before the function, you need to record the current time using time.Now(). Then, after executing the measured block, you can check how much time has elapsed since this time using time.Since() function.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func main() { start := time.Now() time.Sleep(2 * time.Second) log.Printf(\u0026#34;main, execution time %s\\n\u0026#34;, time.Since(start)) } Output:\n2021/08/10 14:32:13 main, execution time 2.003051562s You can shorten the measuring time procedure to one-liner using defer statement. The track function in the example below takes the name of the measured code block (\u0026quot;main\u0026quot;) and returns a closure function that calculates the time elapsed since the call of the track. You only need to call this function at the end of the code block using defer statement that defers execution until the current function (main() in the example below) returns.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;time\u0026#34; ) func track(name string) func() { start := time.Now() return func() { log.Printf(\u0026#34;%s, execution time %s\\n\u0026#34;, name, time.Since(start)) } } func main() { defer track(\u0026#34;main\u0026#34;)() // do not forget about the second parentheses time.Sleep(2 * time.Second) } Output:\n2021/08/10 14:32:39 main, execution time 2.004788787s ","date":"10 August 2021","permalink":"https://gosamples.dev/measure-time/","section":"Tutorials","summary":"","title":"⏲️ Measure execution time in Go"},{"content":"The Go standard library has many functions that allow listing files in a folder. You can list only top-level content of a folder or go through all files and directories recursively in a nested directory structure, as well as list files matching a specific pattern.\nIn all examples we use a folder tree:\ntestFolder ├── file1.go ├── file2.txt └── folder1 └── fileInFolder1.txt List files in a directory by using ioutil.ReadDir #Use ioutil.ReadDir when you want to retrieve files at the top-level of the directory tree.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;io/ioutil\u0026#34; \u0026#34;log\u0026#34; ) func main() { files, err := ioutil.ReadDir(\u0026#34;testFolder\u0026#34;) if err != nil { log.Fatal(err) } for _, f := range files { fmt.Println(f.Name()) } } Output:\nfile1.go file2.txt folder1 List files in a directory by using os.File.Readdir #The function os.File.Readdir works in the same way as ioutil.ReadDir, but it does not sort the result list by name.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { dir, err := os.Open(\u0026#34;testFolder\u0026#34;) if err != nil { log.Fatal(err) } files, err := dir.Readdir(-1) if err != nil { log.Fatal(err) } for _, f := range files { fmt.Println(f.Name()) } } Output:\nfile2.txt file1.txt folder1 List files recursively by using filepath.Walk #Go provides a convenient function filepath.Walk(root string, fn WalkFunc) error to list files recursively. It starts at the root folder and calls fn WalkFunc function for each file and directory in the tree, in lexical order.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; \u0026#34;path/filepath\u0026#34; ) func main() { err := filepath.Walk(\u0026#34;testFolder\u0026#34;, func(path string, _ os.FileInfo, err error) error { if err != nil { return err } fmt.Println(path) return nil }) if err != nil { log.Fatal(err) } } Output:\ntestFolder testFolder/file1.go testFolder/file2.txt testFolder/folder1 testFolder/folder1/fileInFolder1.txt List files that match given pattern by using filepath.Glob #If you are interested only in files that match a given pattern, you can use filepath.Glob, for example, to list all files with .go extension 🙂. Pattern syntax can be found here.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;path/filepath\u0026#34; ) func main() { files, err := filepath.Glob(\u0026#34;testFolder/*.go\u0026#34;) if err != nil { log.Fatal(err) } for _, file := range files { fmt.Println(file) } } Output:\ntestFolder/file1.go ","date":"9 August 2021","permalink":"https://gosamples.dev/list-files/","section":"Tutorials","summary":"","title":"📁 List files in a directory in Go"},{"content":"Access to files in Go is provided by the os package. When the file does not exist, functions of this package return os.ErrNotExist error. As a result, to verify that the file exists, you need to check whether you received this error or not, for example, after opening the file when you want to do something with it like reading the first 100 bytes:\npackage main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func read100Bytes(path string) ([]byte, error) { file, err := os.Open(path) if errors.Is(err, os.ErrNotExist) { return nil, errors.New(\u0026#34;file not exists error\u0026#34;) } data := make([]byte, 100) _, err = file.Read(data) return data, err } func main() { path := \u0026#34;/foo/bar/file.go\u0026#34; data, err := read100Bytes(path) if err != nil { log.Fatal(err) } fmt.Println(string(data)) } Output:\n2021/08/05 18:30:46 file not exists error exit status 1 It\u0026rsquo;s also possible to check if a file exists without doing anything with it, but keep in mind that if you later want to do something with it, such as opening it, you should also check its existence as it may have been modified or deleted in the meantime:\npackage main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; ) func exists(path string) bool { _, err := os.Stat(path) return !errors.Is(err, os.ErrNotExist) } func main() { path := \u0026#34;/foo/bar/file.go\u0026#34; fileExists := exists(path) fmt.Printf(\u0026#34;%s exists: %t\\n\u0026#34;, path, fileExists) } Output:\n/foo/bar/file.go exists: false ","date":"5 August 2021","permalink":"https://gosamples.dev/file-exists/","section":"Tutorials","summary":"","title":"📂 Check if a file exists in Go"},{"content":"Since Go 1.13, we have new helpful ways to find out the type of error, even if we use error wrapping. If we want to check if a given error matches another specific error, we need to use Is() function from the errors package. If we are interested in whether the error is of a given type, we should call the As() function.\nIs() function #In the example below, we can see that the function validateInput returns an error for badInput. This error is ErrBadInput wrapped in an error created by fmt.Errorf(). Using the Is(err, target error) bool function, we can detect the ErrBadInput even if it is wrapped since this function checks if any error in the chain of wrapped errors matches the target. Therefore, this form should be preferable to comparison if err == ErrBadInput.\npackage main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; ) const badInput = \u0026#34;abc\u0026#34; var ErrBadInput = errors.New(\u0026#34;bad input\u0026#34;) func validateInput(input string) error { if input == badInput { return fmt.Errorf(\u0026#34;validateInput: %w\u0026#34;, ErrBadInput) } return nil } func main() { input := badInput err := validateInput(input) if errors.Is(err, ErrBadInput) { fmt.Println(\u0026#34;bad input error\u0026#34;) } } Output:\nbad input error As() function #Similar to Is(), the As(err error, target interface{}) bool checks if any error in the chain of wrapped errors matches the target. The difference is that this function checks whether the error has a specific type, unlike the Is(), which examines if it is a particular error object. Because As considers the whole chain of errors, it should be preferable to the type assertion if e, ok := err.(*BadInputError); ok.\ntarget argument of the As(err error, target interface{}) bool function should be a pointer to the error type, which in this case is *BadInputError\npackage main import ( \u0026#34;errors\u0026#34; \u0026#34;fmt\u0026#34; ) const badInput = \u0026#34;abc\u0026#34; type BadInputError struct { input string } func (e *BadInputError) Error() string { return fmt.Sprintf(\u0026#34;bad input: %s\u0026#34;, e.input) } func validateInput(input string) error { if input == badInput { return fmt.Errorf(\u0026#34;validateInput: %w\u0026#34;, \u0026amp;BadInputError{input: input}) } return nil } func main() { input := badInput err := validateInput(input) var badInputErr *BadInputError if errors.As(err, \u0026amp;badInputErr) { fmt.Printf(\u0026#34;bad input error occured: %s\\n\u0026#34;, badInputErr) } } Output:\nbad input error occured: bad input: abc ","date":"4 August 2021","permalink":"https://gosamples.dev/check-error-type/","section":"Tutorials","summary":"","title":"🐛 Handle errors in Go with errors.Is() and errors.As()"},{"content":"In everyday programming work (especially as a web developer), you often have to debug and analyze JSON responses. In such cases, it is good to display them with an appropriate indentation for better readability, which is often called pretty printing or beautifying JSON. In Go, we can do this in several ways using the encoding/json package.\nJSON pretty print by marshaling value #Function json.MarshalIndent generates JSON encoding of the value with indentation. You can specify a prefix of each JSON line and indent copied one or more times according to the indentation level. In our example, we pretty-print JSON using four spaces for indentation.\npackage main import ( \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func PrettyStruct(data interface{}) (string, error) { val, err := json.MarshalIndent(data, \u0026#34;\u0026#34;, \u0026#34; \u0026#34;) if err != nil { return \u0026#34;\u0026#34;, err } return string(val), nil } type Fruit struct { Name string `json:\u0026#34;name\u0026#34;` Color string `json:\u0026#34;color\u0026#34;` } func main() { fruit := Fruit{ Name: \u0026#34;Strawberry\u0026#34;, Color: \u0026#34;red\u0026#34;, } res, err := PrettyStruct(fruit) if err != nil { log.Fatal(err) } fmt.Println(res) } JSON pretty print by encoding value #If you use json.Encode, you can set indentation through Encoder.SetIndent method similarly to as in marshaling, by defining a prefix and indent.\npackage main import ( \u0026#34;bytes\u0026#34; \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; ) func PrettyEncode(data interface{}, out io.Writer) error { enc := json.NewEncoder(out) enc.SetIndent(\u0026#34;\u0026#34;, \u0026#34; \u0026#34;) if err := enc.Encode(data); err != nil { return err } return nil } type Fruit struct { Name string `json:\u0026#34;name\u0026#34;` Color string `json:\u0026#34;color\u0026#34;` } func main() { fruit := Fruit{ Name: \u0026#34;Strawberry\u0026#34;, Color: \u0026#34;red\u0026#34;, } var buffer bytes.Buffer err := PrettyEncode(fruit, \u0026amp;buffer) if err != nil { log.Fatal(err) } fmt.Println(buffer.String()) } Pretty print JSON string #Package encoding/json also has a useful function json.Indent to beautify JSON string without indentation to JSON with indentation. The function needs the source JSON, output buffer, prefix, and indent.\npackage main import ( \u0026#34;bytes\u0026#34; \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) func PrettyString(str string) (string, error) { var prettyJSON bytes.Buffer if err := json.Indent(\u0026amp;prettyJSON, []byte(str), \u0026#34;\u0026#34;, \u0026#34; \u0026#34;); err != nil { return \u0026#34;\u0026#34;, err } return prettyJSON.String(), nil } func main() { fruitJSON := `{\u0026#34;name\u0026#34;: \u0026#34;Strawberry\u0026#34;, \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34;}` res, err := PrettyString(fruitJSON) if err != nil { log.Fatal(err) } fmt.Println(res) } All methods print JSON string with indentation:\n{ \u0026#34;name\u0026#34;: \u0026#34;Strawberry\u0026#34;, \u0026#34;color\u0026#34;: \u0026#34;red\u0026#34; } ","date":"3 August 2021","permalink":"https://gosamples.dev/pretty-print-json/","section":"Tutorials","summary":"","title":"🗃️ 3 ways to pretty print JSON in Go"},{"content":"In Go, you can easily convert a map to a JSON string using encoding/json package. It does not matter if the map contains strings, arrays, structures, numerical values, or another map. The only thing you should remember is that JSON allows only string keys, so if you have an integer key in your map, it will be converted to a string.\npackage main import ( \u0026#34;encoding/json\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; ) type color struct { Name string `json:\u0026#34;name\u0026#34;` HexCode string `json:\u0026#34;hex_code\u0026#34;` } func main() { data := make(map[string]interface{}) data = map[string]interface{}{ \u0026#34;best_fruit\u0026#34;: \u0026#34;apple\u0026#34;, // string value \u0026#34;best_vegetables\u0026#34;: []string{\u0026#34;potato\u0026#34;, \u0026#34;carrot\u0026#34;, \u0026#34;cabbage\u0026#34;}, // array value \u0026#34;best_websites\u0026#34;: map[int]interface{}{ // map value 1: \u0026#34;gosamples.dev\u0026#34;, // integer key, string value }, \u0026#34;best_color\u0026#34;: color{ Name: \u0026#34;red\u0026#34;, HexCode: \u0026#34;#FF0000\u0026#34;, }, // struct value } jsonBytes, err := json.MarshalIndent(data, \u0026#34;\u0026#34;, \u0026#34; \u0026#34;) if err != nil { log.Fatal(err) } fmt.Println(string(jsonBytes)) } json.MarshalIndent produces JSON encoding of the map with indentation. If you need output without indentation, use json.Marshal.\nOutput:\n{ \u0026#34;best_color\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;hex_code\u0026#34;: \u0026#34;#FF0000\u0026#34; }, \u0026#34;best_fruit\u0026#34;: \u0026#34;apple\u0026#34;, \u0026#34;best_vegetables\u0026#34;: [ \u0026#34;potato\u0026#34;, \u0026#34;carrot\u0026#34;, \u0026#34;cabbage\u0026#34; ], \u0026#34;best_websites\u0026#34;: { \u0026#34;1\u0026#34;: \u0026#34;gosamples.dev\u0026#34; } } ","date":"1 August 2021","permalink":"https://gosamples.dev/map-to-json/","section":"Tutorials","summary":"","title":"🗺️ Convert map to JSON in Go"},{"content":"Use strconv.FormatInt function to convert an integer variable to a string in Go.\nint64 to a decimal string #var number int64 = 12 str := strconv.FormatInt(number, 10) fmt.Println(str) int, int32, int16, int8 to a decimal string #var number int = 12 // you can use any integer here: int32, int16, int8 str := strconv.FormatInt(int64(number), 10) fmt.Println(str) To convert int to string you can also use strconv.Itoa which is equivalent to strconv.FormatInt(int64(i), 10).\nnumber := 12 str := strconv.Itoa(number) fmt.Println(str) int64 to a hexadecimal string #var number int64 = 12 // you can use any integer here: int, int32, int16, int8 str := strconv.FormatInt(number, 16) fmt.Println(str) int64 to an octal string #var number int64 = 12 // int, int32, int16, int8 str := strconv.FormatInt(number, 8) fmt.Println(str) int64 to a binary string #var number int64 = 12 // int, int32, int16, int8 str := strconv.FormatInt(number, 2) fmt.Println(str) ","date":"23 July 2021","permalink":"https://gosamples.dev/convert-int-to-string/","section":"Tutorials","summary":"","title":"🔢 Convert int to string in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/integer/","section":"Tags","summary":"","title":"Integer"},{"content":"CSV is a popular data format used by Excel, Google Sheets and other spreadsheet apps to save and load tabular data. In this format, rows are separated by a newline character and each cell in a row is separated by a comma (or a tab in TSV format). Go has great built-in support for writing and reading CSV files. Check out how easy it is to write a simple CSV file.\nSee also our example of how to read a CSV file in Go\npackage main import ( \u0026#34;encoding/csv\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { data := [][]string{ {\u0026#34;vegetables\u0026#34;, \u0026#34;fruits\u0026#34;}, {\u0026#34;carrot\u0026#34;, \u0026#34;banana\u0026#34;}, {\u0026#34;potato\u0026#34;, \u0026#34;strawberry\u0026#34;}, } // create a file file, err := os.Create(\u0026#34;result.csv\u0026#34;) if err != nil { log.Fatal(err) } defer file.Close() // initialize csv writer writer := csv.NewWriter(file) defer writer.Flush() // write all rows at once writer.WriteAll(data) // write single row extraData := []string{\u0026#34;lettuce\u0026#34;, \u0026#34;raspberry\u0026#34;} writer.Write(extraData) } In the first step, you need to create a file where the CSV data can be saved. You can do this with the Create function from the os package. Be sure to call file.Close() to close the file after the data has been written.\nThen, we initialize csv.Writer from the encoding/csv package, that allows us to write data in CSV format. It\u0026rsquo;s a buffered writer, so we should call writer.Flush() at the end of the write to make sure all data is saved to the file.\nThe CSV writer has two methods for saving data rows. We can use writer.WriteAll() method when we know all the data at the time of writing, or writer.Write() to write the data line by line.\nWrite to a TSV file #The standard separator of csv.Writer is a comma, but you can easily change this by replacing the comma rune with another character:\nwriter.Comma = \u0026#39;\\t\u0026#39; In this way, our writer uses TSV (tab-separated values) encoding that is also a commonly used tabular data format.\n","date":"1 June 2021","permalink":"https://gosamples.dev/write-csv/","section":"Tutorials","summary":"","title":"✒️ Write to a CSV file in Go"},{"content":"Is there a case-insensitive string comparison function in Go? Of course! Although the name does not seem to indicate it, strings.EqualFold deals with it:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { foo1 := \u0026#34;foo\u0026#34; foo2 := \u0026#34;FOO\u0026#34; fmt.Println(strings.EqualFold(foo1, foo2)) } You may ask now why we can\u0026rsquo;t convert both strings to upper or lowercase and, in this way, compare if they are case-insensitive equal. Of course, it works, but not for any case and any language. For example, in Greek, there are 3 forms of sigma letter:\ng1 := \u0026#34;ς\u0026#34; // a final lowercase sigma g2 := \u0026#34;Σ\u0026#34; // a capital sigma g3 := \u0026#34;σ\u0026#34; // a non-final sigma fmt.Println(strings.ToLower(g1)) fmt.Println(strings.ToLower(g2)) fmt.Println(strings.ToLower(g3)) fmt.Println(strings.EqualFold(g1, g2)) fmt.Println(strings.EqualFold(g1, g3)) fmt.Println(strings.EqualFold(g2, g3)) Output:\nς σ σ true true true Converting them to lowercase doesn\u0026rsquo;t give the same form, but a comparison using strings.EqualFold informs that they are equal. This is because strings.EqualFold uses case folding (now it\u0026rsquo;s clear why the function is named EqualFold) method which respects the case rules of different languages, so it always should be preffered method of case-insensitive comparison.\n","date":"25 May 2021","permalink":"https://gosamples.dev/case-insensitive-string-comparison/","section":"Tutorials","summary":"","title":"🙌 Case-insensitive string comparison in Go"},{"content":"It\u0026rsquo;s really simple to check if a given string starts with another substring in Go. In many programming languages, there is a startsWith() function to do this. In Go, we have HasPrefix() from the strings package. It returns true when a substring is the prefix of a string or false otherwise.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) const name = \u0026#34;GOSAMPLES\u0026#34; func main() { fmt.Printf(\u0026#34;GO is at the beginning of GOSAMPLES: %t\\n\u0026#34;, strings.HasPrefix(name, \u0026#34;GO\u0026#34;)) fmt.Printf(\u0026#34;SAMPLES is at the beginning of GOSAMPLES: %t\\n\u0026#34;, strings.HasPrefix(name, \u0026#34;SAMPLES\u0026#34;)) } Output:\nGO is at the beginning of GOSAMPLES: true SAMPLES is at the beginning of GOSAMPLES: false ","date":"11 May 2021","permalink":"https://gosamples.dev/starts-with/","section":"Tutorials","summary":"","title":"🏁 Check if a string starts with a substring in Go"},{"content":"Go has excellent built-in support for file operations. Using the os package, you can easily open, read from, write to and close the file. In this example, we focus on writing data to a file. We show you how you can write text and binary data in different ways - entire data at once, line by line, as an array of bytes in a specific place, or in a buffered manner.\nWrite the entire content to a file at once #The shortest way of writing data to a file is to use the os.WriteFile() function. It takes three input parameters:\nPath to the file that we want to write to Byte data which we want to write to the file Permission bits of the file that will be created Creating and closing the file is done by the function itself, so it\u0026rsquo;s no need to create or close the file before and after writing.\nIf you are using the Go version earlier than 1.16, you will find the WriteFile() function in the ioutil package.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { if err := os.WriteFile(\u0026#34;file.txt\u0026#34;, []byte(\u0026#34;Hello GOSAMPLES!\u0026#34;), 0666); err != nil { log.Fatal(err) } } Write text data to a file line by line #If you have your file\u0026rsquo;s lines in separate variables, an array, or want to do some processing before writing a single line, you can write the data line by line using the func (*File) WriteString() method. All you need to do is create a file, write your strings to it, and finally close the file.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) var lines = []string{ \u0026#34;Go\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;best\u0026#34;, \u0026#34;programming\u0026#34;, \u0026#34;language\u0026#34;, \u0026#34;in\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;world\u0026#34;, } func main() { // create file f, err := os.Create(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file defer f.Close() for _, line := range lines { _, err := f.WriteString(line + \u0026#34;\\n\u0026#34;) if err != nil { log.Fatal(err) } } } Write byte data to a file #As with writing strings line by line, we can also write byte data using the func (*File) Write() method or func (*File) WriteAt() if you want to write data at a given offset.\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) var bytes = []byte{ 0x47, // G 0x4f, // O 0x20, // \u0026lt;space\u0026gt; 0x20, // \u0026lt;space\u0026gt; 0x20, // \u0026lt;space\u0026gt; 0x50, // P 0x4c, // L 0x45, // E 0x53, // S } var additionalBytes = []byte{ 0x53, // S 0x41, // A 0x4d, // M } func main() { // create file f, err := os.Create(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file defer f.Close() // write bytes to the file _, err = f.Write(bytes) if err != nil { log.Fatal(err) } // write additional bytes to the file, start at index 2 _, err = f.WriteAt(additionalBytes, 2) if err != nil { log.Fatal(err) } } Write formatted strings to a file #In addition to the File methods, we can use fmt.Fprintln() function to write data to a file. This function formats its operands, adds spaces between them, a new line at the end, and writes the output to the writer (first argument). It\u0026rsquo;s great for simple line formatting or writing the string representation of a struct to a file.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) var lines = []string{ \u0026#34;Go\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;best\u0026#34;, \u0026#34;programming\u0026#34;, \u0026#34;language\u0026#34;, \u0026#34;in\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;world\u0026#34;, } func main() { // create file f, err := os.Create(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file defer f.Close() for _, line := range lines { _, err := fmt.Fprintln(f, \u0026#34;*\u0026#34;, line, \u0026#34;*\u0026#34;) if err != nil { log.Fatal(err) } } } Write to a file using a buffered writer #If you frequently write a small amount of data to a file, it can hurt the performance of your program. Each write is a costly system call, and if you don\u0026rsquo;t need immediate file updates, it is a better idea to group these small writes into one. To do this, we can use bufio.Writer structure. Its writing functions do not save data directly to the file but keep it until the buffer underneath is full (default size is 4096 bytes) or the Flush() method is called. So make sure to call Flush() after the completed write to save the remaining data to the file.\npackage main import ( \u0026#34;bufio\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) var lines = []string{ \u0026#34;Go\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;best\u0026#34;, \u0026#34;programming\u0026#34;, \u0026#34;language\u0026#34;, \u0026#34;in\u0026#34;, \u0026#34;the\u0026#34;, \u0026#34;world\u0026#34;, } func main() { // create file f, err := os.Create(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file defer f.Close() // create new buffer buffer := bufio.NewWriter(f) for _, line := range lines { _, err := buffer.WriteString(line + \u0026#34;\\n\u0026#34;) if err != nil { log.Fatal(err) } } // flush buffered data to the file if err := buffer.Flush(); err != nil { log.Fatal(err) } } ","date":"29 April 2021","permalink":"https://gosamples.dev/write-file/","section":"Tutorials","summary":"","title":"✍️ Write to a file in Go"},{"content":"Reading files is one of the most common tasks in everyday programmer\u0026rsquo;s work. You can do it in different ways depending on your needs. In this tutorial, we show you how to read the entire file at once, line by line, word by word, and in chunks. All of these methods are very simple in Go 🙂.\nRead an entire file #The simplest way of reading a text or binary file in Go is to use the ReadFile() function from the os package. This function reads the entire content of the file into a byte slice, so you should be careful when trying to read a large file - in this case, you should read the file line by line or in chunks. For small files, this function is more than sufficient.\nIf you are using the Go version earlier than 1.16, you will find the ReadFile() function in the ioutil package.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { content, err := os.ReadFile(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } fmt.Println(string(content)) } Output:\nThis is txt file read by Go! Read a file line by line #To read a file line by line, we can use a convenient bufio.Scanner structure. Its constructor, NewScanner(), takes an opened file (remember to close the file after the operation is done, for example, by using defer statement) and lets you read subsequent lines through Scan() and Text() methods. Using Err() method, you can check errors encountered during file reading.\npackage main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { // open file f, err := os.Open(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file at the end of the program defer f.Close() // read the file line by line using scanner scanner := bufio.NewScanner(f) for scanner.Scan() { // do something with a line fmt.Printf(\u0026#34;line: %s\\n\u0026#34;, scanner.Text()) } if err := scanner.Err(); err != nil { log.Fatal(err) } } Output:\nline: Hello World! line: This is txt file read by Go! Read a file word by word #Reading a file word by word is almost the same as reading line by line. You only need to change the split function of the Scanner from the default ScanLines() to ScanWords().\npackage main import ( \u0026#34;bufio\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) func main() { // open file f, err := os.Open(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file at the end of the program defer f.Close() // read the file word by word using scanner scanner := bufio.NewScanner(f) scanner.Split(bufio.ScanWords) for scanner.Scan() { // do something with a word fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { log.Fatal(err) } } Output:\nWorld! This is txt file read by Go! Read a file in chunks #When you have a very large file or don\u0026rsquo;t want to store the entire file in memory, you can read the file in fixed-size chunks. In this case, you need to create a byte slice of the specified size (chunkSize in the example) as a buffer for storing the subsequent read bytes. Using Read() method of the File type, we can load the next chunk of the file data. The reading loop finishes when an io.EOF error occurs, indicating the end of the file.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;io\u0026#34; \u0026#34;log\u0026#34; \u0026#34;os\u0026#34; ) const chunkSize = 10 func main() { // open file f, err := os.Open(\u0026#34;file.txt\u0026#34;) if err != nil { log.Fatal(err) } // remember to close the file at the end of the program defer f.Close() buf := make([]byte, chunkSize) for { n, err := f.Read(buf) if err != nil \u0026amp;\u0026amp; err != io.EOF { log.Fatal(err) } if err == io.EOF { break } fmt.Println(string(buf[:n])) } } Output:\nd! This is txt file read by Go ! ","date":"27 April 2021","permalink":"https://gosamples.dev/read-file/","section":"Tutorials","summary":"","title":"📖 Read a file in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/crypto/","section":"Tags","summary":"","title":"Crypto"},{"content":"Random numbers are useful for games, simulations, shuffling, sampling, and test data. In Go 1.22+, the recommended package for non-secure randomness is math/rand/v2, which provides modern generators and a clearer API. For anything security-sensitive (tokens, passwords, keys), use crypto/rand instead. 🚀\nWhat Is Random Number Generation in Go? #math/rand/v2 uses pseudo-random number generators (PRNGs). PRNGs are fast and repeatable, but they are deterministic once the internal state is known. That makes them great for simulations and games, and a bad fit for security. If you start a generator with the same seed, you will get the same sequence again, which is handy for tests.\nWhen to Use Random Numbers # Simulations, games, shuffling, sampling: use math/rand/v2 Security-sensitive values (tokens, passwords, keys): use crypto/rand Repeatable tests: use a fixed seed with a custom *rand.Rand How to Generate Random Numbers in Go (math/rand/v2) #Full working example using math/rand/v2:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;math/rand/v2\u0026#34; ) func randIntRange(min, max int) int { if max \u0026lt;= min { panic(\u0026#34;max must be greater than min\u0026#34;) } return min + rand.IntN(max-min) } func randFloatRange(min, max float64) float64 { if max \u0026lt;= min { panic(\u0026#34;max must be greater than min\u0026#34;) } return min + rand.Float64()*(max-min) } func main() { fmt.Println(\u0026#34;any int:\u0026#34;, rand.Int()) fmt.Printf(\u0026#34;any float64: %.6f\\n\u0026#34;, rand.Float64()) fmt.Println(\u0026#34;int in [5, 10):\u0026#34;, randIntRange(5, 10)) fmt.Printf(\u0026#34;float64 in [2.4, 3.2): %.6f\\n\u0026#34;, randFloatRange(2.4, 3.2)) } Example output:\nany int: 5696350091330895579 any float64: 0.764513 int in [5, 10): 6 float64 in [2.4, 3.2): 3.142109 How it works:\nrand.Int returns a non-negative int. rand.Float64 returns a float in [0.0, 1.0). Int range: min + rand.IntN(max-min) produces [min, max) using rand.IntN. Float range: min + rand.Float64()*(max-min) produces [min, max) using rand.Float64. Modern Go Features (Go 1.22+): math/rand/v2 #The new math/rand/v2 package is recommended for new code because:\nIt includes modern generators like PCG and ChaCha8 (still not cryptographically secure). It adds clearer range helpers such as IntN, Int64N, UintN, and the generic N. It removes the old global seeding pattern; if you want repeatable output, create your own generator with rand.New. PCG stands for Permuted Congruential Generator. It is a fast PRNG family with good statistical quality for simulations, games, and tests.\nReproducible random numbers for tests #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;math/rand/v2\u0026#34; ) func main() { r := rand.New(rand.NewPCG(1, 2)) fmt.Println(r.IntN(100)) fmt.Println(r.IntN(100)) } Use a fixed seed for tests so results stay stable. This example builds a local generator with rand.New and rand.NewPCG, which returns a *rand.Rand you can pass around.\nSecure Random Numbers with crypto/rand #For tokens, passwords, and security-sensitive data, use crypto/rand. It reads from the operating system\u0026rsquo;s cryptographically secure random source.\npackage main import ( \u0026#34;crypto/rand\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;math/big\u0026#34; ) func secureIntRange(min, max int64) (int64, error) { if max \u0026lt;= min { return 0, fmt.Errorf(\u0026#34;max must be greater than min\u0026#34;) } n, err := rand.Int(rand.Reader, big.NewInt(max-min)) if err != nil { return 0, err } return min + n.Int64(), nil } func main() { v, err := secureIntRange(1000, 10000) if err != nil { panic(err) } fmt.Println(\u0026#34;secure int in [1000, 10000):\u0026#34;, v) } Like math/rand/v2, crypto/rand.Int treats the upper bound as exclusive, so the range is [min, max). This uses crypto/rand.Int with rand.Reader and big.NewInt to set the upper bound.\nGotchas # math/rand/v2 is not for secrets; use crypto/rand for tokens and passwords. Range helpers like IntN expect max \u0026gt; min; otherwise you will panic on IntN(0). A *rand.Rand is not safe for concurrent use without synchronization. Best Practices # Validate ranges so max \u0026gt; min and avoid passing 0 to IntN. Use math/rand/v2 for simulations and tests, not for secrets. Create a local *rand.Rand with rand.NewPCG when you need reproducible output. The top-level functions are concurrency-safe, but a *rand.Rand needs synchronization if shared. Related Topics # Generate random strings in Go: Build IDs, salts, and test data. Generate UUIDs in Go: Unique identifiers for records and requests. Int min/max in Go: Keep ranges and bounds correct. Float64 min/max in Go: Safe bounds for float ranges. Round floats in Go: Format and round random floats. Tested with Go 1.25+ | Last verified: December 2025\nHappy coding! 🎉\n","date":"22 April 2021","permalink":"https://gosamples.dev/random-numbers/","section":"Tutorials","summary":"","title":"Generate Random Numbers in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/environment/","section":"Tags","summary":"","title":"Environment"},{"content":"Environment variables are key-value strings provided by the operating system. They are commonly used to pass configuration into Go programs without hard-coding secrets or settings. In Go, you work with them through the standard os package.\nEach variable has a key (like APP_PORT) and a value (like 8080). Environment variables are scoped to the current process and are inherited by child processes, which is why tools like Docker and CI pipelines rely on them.\nRead environment variables safely #Use os.LookupEnv to tell the difference between an empty value and a missing variable. If you only use os.Getenv, a missing variable looks the same as an empty one. You can also build a small helper to provide defaults.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; ) func getenvDefault(key, fallback string) string { if val, ok := os.LookupEnv(key); ok { return val } return fallback } func main() { _ = os.Setenv(\u0026#34;APP_EMPTY\u0026#34;, \u0026#34;\u0026#34;) _ = os.Setenv(\u0026#34;APP_PORT\u0026#34;, \u0026#34;8080\u0026#34;) fmt.Printf(\u0026#34;Getenv(APP_EMPTY): %q\\n\u0026#34;, os.Getenv(\u0026#34;APP_EMPTY\u0026#34;)) val, ok := os.LookupEnv(\u0026#34;APP_EMPTY\u0026#34;) fmt.Printf(\u0026#34;LookupEnv(APP_EMPTY): ok=%t value=%q\\n\u0026#34;, ok, val) fmt.Printf(\u0026#34;APP_PORT with default: %s\\n\u0026#34;, getenvDefault(\u0026#34;APP_PORT\u0026#34;, \u0026#34;3000\u0026#34;)) fmt.Printf(\u0026#34;APP_MISSING with default: %s\\n\u0026#34;, getenvDefault(\u0026#34;APP_MISSING\u0026#34;, \u0026#34;3000\u0026#34;)) } Output:\nGetenv(APP_EMPTY): \u0026#34;\u0026#34; LookupEnv(APP_EMPTY): ok=true value=\u0026#34;\u0026#34; APP_PORT with default: 8080 APP_MISSING with default: 3000 Set and unset variables #os.Setenv and os.Unsetenv affect only the current process (and its children), not your shell. If you need a variable available in your shell, set it with export or your shell config file.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; ) func main() { const key = \u0026#34;APP_TOKEN\u0026#34; if err := os.Setenv(key, \u0026#34;secret-123\u0026#34;); err != nil { panic(err) } fmt.Printf(\u0026#34;After Setenv: %s=%s\\n\u0026#34;, key, os.Getenv(key)) if err := os.Unsetenv(key); err != nil { panic(err) } _, ok := os.LookupEnv(key) fmt.Printf(\u0026#34;After Unsetenv: ok=%t\\n\u0026#34;, ok) } Output:\nAfter Setenv: APP_TOKEN=secret-123 After Unsetenv: ok=false List variables and clear the environment #Use os.Environ to list the process environment. os.Clearenv removes everything for the current process. This is handy for short-lived tools and tests.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; \u0026#34;strings\u0026#34; ) func main() { _ = os.Setenv(\u0026#34;APP_NAME\u0026#34;, \u0026#34;gosamples\u0026#34;) _ = os.Setenv(\u0026#34;APP_ENV\u0026#34;, \u0026#34;dev\u0026#34;) count := 0 for _, env := range os.Environ() { if strings.HasPrefix(env, \u0026#34;APP_\u0026#34;) { fmt.Println(env) count++ } } fmt.Printf(\u0026#34;APP_ variables: %d\\n\u0026#34;, count) os.Clearenv() fmt.Printf(\u0026#34;After Clearenv: %d variables\\n\u0026#34;, len(os.Environ())) } Output:\nAPP_NAME=gosamples APP_ENV=dev APP_ variables: 2 After Clearenv: 0 variables Expand variables in strings (related utilities) #Use os.ExpandEnv for $VAR or ${VAR} expansion, and os.Expand when you want custom handling (for example, a fallback value).\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;os\u0026#34; ) func main() { _ = os.Setenv(\u0026#34;APP_HOME\u0026#34;, \u0026#34;/srv/app\u0026#34;) _ = os.Setenv(\u0026#34;USER\u0026#34;, \u0026#34;gosamples\u0026#34;) fmt.Println(os.ExpandEnv(\u0026#34;$APP_HOME/logs\u0026#34;)) expanded := os.Expand(\u0026#34;User=${USER}, app=${APP_NAME}\u0026#34;, func(key string) string { if key == \u0026#34;APP_NAME\u0026#34; { return \u0026#34;gosamples\u0026#34; } return os.Getenv(key) }) fmt.Println(expanded) } Output:\n/srv/app/logs User=gosamples, app=gosamples Common mistakes # ❌ Using os.Getenv to check if a variable exists. ✅ Use os.LookupEnv to detect missing keys. ❌ Expecting os.Setenv to modify your shell environment. ✅ Use export in the shell for that. ❌ Calling os.Clearenv in shared libraries. ✅ Reserve it for tests or short-lived tools. Best practices # Treat environment variables as immutable configuration once your app starts. Document required variables and defaults in README or sample config. Avoid storing secrets in code; read them from env or a secrets manager. Related topics # Read a YAML file in Go - load configuration files Read a file in Go - ingest config from disk Write a file in Go - persist generated config Check Go version in Go - tooling diagnostics Get local IP address in Go - environment info Tested with Go 1.25+ | Last verified: December 2025 🎉\n","date":"21 April 2021","permalink":"https://gosamples.dev/environment-variables/","section":"Tutorials","summary":"","title":"How to use environment variables in Go (get, set, expand)"},{"content":"","date":null,"permalink":"https://gosamples.dev/categories/tooling/","section":"Categories","summary":"","title":"Tooling"},{"content":"Go does not have a while keyword, but you can express the same logic with the for statement. It is the idiomatic way to write while-style loops in Go.\nWhile-style loop in Go #Classic for has the form:\nfor initialization; condition; post-condition { } where:\ninitialization is executed before the first iteration condition is boolean expression evaluated before every iteration post-condition is executed after every iteration When we omit the initialization and post-condition statements, we get the conditional for loop that has the same effect as while loop available in other programming languages:\nfor condition { } Example #package main import \u0026#34;fmt\u0026#34; func main() { i := 1 var gte1000 bool for !gte1000 { i *= 10 fmt.Println(i) if i \u0026gt;= 1000 { gte1000 = true } } } Since Go\u0026rsquo;s for statement is very flexible, we can initialize the condition variable inside the loop and ignore the post-condition statement (notice ; at the end of the for declaration - we use classic for here):\nExample with inline initialization #package main import \u0026#34;fmt\u0026#34; func main() { i := 1 for gte1000 := false; !gte1000; { i *= 10 fmt.Println(i) if i \u0026gt;= 1000 { gte1000 = true } } } Output:\n100 1000 Common mistakes #❌ Forgetting to update the condition:\nfor i \u0026lt; 10 { fmt.Println(i) } ✅ Always update the loop variable:\nfor i \u0026lt; 10 { fmt.Println(i) i++ } ❌ Using a for loop when a range loop is clearer:\nfor i := 0; i \u0026lt; len(items); i++ { /* ... */ } ✅ Prefer range for slices and arrays:\nfor _, item := range items { /* ... */ } Best practices # Keep loop conditions simple and easy to read. Use break for early exit and continue to skip iterations. Prefer range when iterating over collections. Related topics # Foreach loop in Go - iterating with range Do while loop in Go - emulate do-while behavior Infinite loop in Go - intentional endless loops Range over a ticker in Go - periodic loops Measure time in Go - timing loop work Tested with Go 1.25+ | Last verified: December 2025 🎉\n","date":"20 April 2021","permalink":"https://gosamples.dev/while-loop/","section":"Tutorials","summary":"","title":"How to write a while loop in Go"},{"content":"String splitting is a common task when parsing user input, environment variables, or CSV-like data. Go offers several standard-library tools for different splitting needs. Below are 8 practical options you can use today.\nSplit a string by separator #To split a string in Go, use the strings.Split() function from the strings package. It splits a string into a list of substrings using the specified delimiter. The output substrings do not contain the separator.\nThe function signature is func Split(s, sep string) []string where\ns is the string to split sep is a separator (delimiter) by which the string is split Example #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; fmt.Printf(\u0026#34;strings.Split(): %#v\\n\u0026#34;, strings.Split(str, \u0026#34;, \u0026#34;)) } Output:\nstrings.Split(): []string{\u0026#34;strawberry\u0026#34;, \u0026#34;blueberry\u0026#34;, \u0026#34;raspberry\u0026#34;} Split a string without removing the separator #To split a string in Go into substrings containing the separator by which they were split, use the strings.SplitAfter() function. It splits a string after each occurrence of the delimiter.\nThe functions signature: func SplitAfter(s, sep string) []string\ns is the string to split sep is a separator (delimiter) by which the string is split Example #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; fmt.Printf(\u0026#34;strings.SplitAfter(): %#v\\n\u0026#34;, strings.SplitAfter(str, \u0026#34;, \u0026#34;)) } Output:\nstrings.SplitAfter(): []string{\u0026#34;strawberry, \u0026#34;, \u0026#34;blueberry, \u0026#34;, \u0026#34;raspberry\u0026#34;} Cut a string into 2 parts #To cut a string on the first occurrence of the delimiter in Go, use the strings.Cut() function. It slices a string and returns the text before and after the separator.\nThe function signature: func Cut(s, sep string) (before, after string, found bool) The strings.Cut() takes a string s and a separator sep as arguments and splits the string s on the first occurrence of the sep. It returns the text before and after the sep, and the boolean value found indicating whether sep appears in the s.\nExample #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; before, after, found := strings.Cut(str, \u0026#34;, \u0026#34;) fmt.Printf(\u0026#34;strings.Cut():\\nbefore: %s\\nafter: %s\\nseparator found: %t\\n\u0026#34;, before, after, found) } Output:\nstrings.Cut(): before: strawberry after: blueberry, raspberry separator found: true Split a string to at most n substrings #To split a string in Go and receive at most n substrings, use the strings.SplitN() function. The last substring in this case will be the unsplit remainder.\nThe function signature: func SplitN(s, sep string, n int) []string\nThe strings.SplitN() function works the same way as strings.Split() except that it finishes after n substrings.\nExample #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; fmt.Printf(\u0026#34;strings.SplitN(): %#v\\n\u0026#34;, strings.SplitN(str, \u0026#34;, \u0026#34;, 2)) } Output:\nstrings.SplitN(): []string{\u0026#34;strawberry\u0026#34;, \u0026#34;blueberry, raspberry\u0026#34;} Split a string without removing the separator to at most n substrings #To split a string in Go into output substrings containing a separator and getting at most n substrings, use the strings.SplitAfterN() function. It splits a string after each occurrence of the delimiter, and the last substring will be the unsplit remainder.\nThe function signature: func SplitAfterN(s, sep string, n int) []string\nThe strings.SplitAfterN() function works the same way as strings.SplitAfter() except that it finishes after n substrings.\nExample #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; fmt.Printf(\u0026#34;strings.SplitAfterN(): %#v\\n\u0026#34;, strings.SplitAfterN(str, \u0026#34;, \u0026#34;, 2)) } Output:\nstrings.SplitAfterN(): []string{\u0026#34;strawberry, \u0026#34;, \u0026#34;blueberry, raspberry\u0026#34;} Split a string by white space characters #To split a string by white space characters in Go, use the strings.Fields() function. It takes a string as an argument and splits it according to the white space characters defined by the unicode.IsSpace() function.\nThe function signature: func Fields(s string) []string\nExample #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; fmt.Printf(\u0026#34;strings.Fields(): %#v\\n\u0026#34;, strings.Fields(str)) } Output:\nstrings.Fields(): []string{\u0026#34;strawberry,\u0026#34;, \u0026#34;blueberry,\u0026#34;, \u0026#34;raspberry\u0026#34;} Split a string by a splitting function #To split a string according to a custom split function in Go, use the strings.FieldsFunc(). As arguments, it gets the string to split and the func(rune) bool function, which should return true if splitting should be done for a given rune.\nThe function signature: func FieldsFunc(s string, f func(rune) bool) []string\nExample #In the example, the string is split on runes that are not Unicode letters.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; \u0026#34;unicode\u0026#34; ) func main() { str := \u0026#34;strawberry, blueberry, raspberry\u0026#34; fmt.Printf(\u0026#34;strings.FieldsFunc(): %#v\\n\u0026#34;, strings.FieldsFunc(str, func(r rune) bool { return !unicode.IsLetter(r) })) } strings.FieldsFunc(): []string{\u0026#34;strawberry\u0026#34;, \u0026#34;blueberry\u0026#34;, \u0026#34;raspberry\u0026#34;} Split a string using the regexp #In Go, you can also split a string using a Regular Expression. To do this, you must first create a new regular expression object Regexp, for example, by calling the regexp.MustCompile() function. The Regexp object has the Split() method that splits a given string s by the regular expression into at most n substrings (the last substring will be the unsplit remainder).\nThe method signature: func (re *Regexp) Split(s string, n int) []string\nExample #package main import ( \u0026#34;fmt\u0026#34; \u0026#34;regexp\u0026#34; ) func main() { str := \u0026#34;strawberry,blueberry, raspberry\u0026#34; regex := regexp.MustCompile(\u0026#34;,\\\\s*\u0026#34;) fmt.Printf(\u0026#34;Regexp.Split(): %#v\\n\u0026#34;, regex.Split(str, -1)) } Output:\nRegexp.Split(): []string{\u0026#34;strawberry\u0026#34;, \u0026#34;blueberry\u0026#34;, \u0026#34;raspberry\u0026#34;} Common mistakes #❌ Using strings.Split when you only need two parts:\nparts := strings.Split(\u0026#34;a=b\u0026#34;, \u0026#34;=\u0026#34;) // extra allocations ✅ Use strings.Cut for two pieces:\nbefore, after, found := strings.Cut(\u0026#34;a=b\u0026#34;, \u0026#34;=\u0026#34;) ❌ Splitting on whitespace with Split:\nparts := strings.Split(\u0026#34;a b\u0026#34;, \u0026#34; \u0026#34;) ✅ Use strings.Fields to handle multiple spaces:\nparts := strings.Fields(\u0026#34;a b\u0026#34;) Best practices # Use strings.Cut or strings.SplitN when you want only the first separator. Prefer strings.Fields for whitespace splitting; it handles multiple spaces and tabs. Use regexp.Split only when you truly need regex; it is slower than simple splits. Related topics # Remove duplicate spaces in Go - normalize whitespace String to uppercase in Go - basic string transforms Concatenate strings in Go - build strings safely Remove non-alphanumeric characters in Go - cleaning input Compare strings in Go - equality and ordering Tested with Go 1.25+ | Last verified: December 2025 🎉\n","date":"19 April 2021","permalink":"https://gosamples.dev/split-string/","section":"Tutorials","summary":"","title":"8 ways to split a string in Go with examples"},{"content":"URL encoding (percent-encoding) makes URLs safe to transmit. To decode an encoded URL in Go, use the net/url package. The most common tools are url.Parse() for full URLs and url.QueryUnescape() / url.PathUnescape() for individual components.\nIf you want to URL encode a path, a query, or the whole URL, see URL Encode in Go post.\nA typical URL consists of the following components:\nscheme://host:port/path?query\nDecode a full URL with url.Parse #The url.Parse() function takes a URL string and returns a url.URL with decoded fields.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { // decode URL by url.Parse parsedURL, err := url.Parse(\u0026#34;https://example.com/foo+bar%21?query=ab%2Bc\u0026amp;query2=de%24f\u0026#34;) if err != nil { log.Fatal(err) return } fmt.Printf(\u0026#34;scheme: %s\\n\u0026#34;, parsedURL.Scheme) fmt.Printf(\u0026#34;host: %s\\n\u0026#34;, parsedURL.Host) fmt.Printf(\u0026#34;path: %s\\n\u0026#34;, parsedURL.Path) fmt.Println(\u0026#34;query args:\u0026#34;) for key, values := range parsedURL.Query() { fmt.Printf(\u0026#34; %s = %s\\n\u0026#34;, key, values[0]) } } Result:\nscheme: https host: example.com path: /foo+bar! query args: query = ab+c query2 = de$f Decode path and query components #Use these helpers when you only have a piece of a URL:\nurl.PathUnescape() for path segments url.QueryUnescape() for query values url.ParseQuery() to decode and parse a full query string into url.Values See the example to compare these functions:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;log\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { // decode path by url.PathUnescape path := \u0026#34;foo+bar%21\u0026#34; unescapedPath, err := url.PathUnescape(path) if err != nil { log.Fatal(err) return } fmt.Printf(\u0026#34;unescaped path: %s\\n\u0026#34;, unescapedPath) // decode query by url.QueryUnescape query := \u0026#34;query=ab%2Bc\u0026amp;query2=de%24f\u0026#34; unescapedQuery, err := url.QueryUnescape(query) if err != nil { log.Fatal(err) return } fmt.Printf(\u0026#34;unescaped query: %s\\n\u0026#34;, unescapedQuery) // decode query and parse by url.ParseQuery parsedQuery, err := url.ParseQuery(query) if err != nil { log.Fatal(err) return } fmt.Println(\u0026#34;parsed query args:\u0026#34;) for key, values := range parsedQuery { fmt.Printf(\u0026#34; %s = %s\\n\u0026#34;, key, values[0]) } } Result:\nunescaped path: foo+bar! unescaped query: query=ab+c\u0026amp;query2=de$f parsed query args: query = ab+c query2 = de$f Common mistakes #❌ Using QueryUnescape on a full URL:\ndecoded, _ := url.QueryUnescape(\u0026#34;https://example.com/?q=a%2Bb\u0026#34;) ✅ Use url.Parse for full URLs and read the components:\nparsed, _ := url.Parse(\u0026#34;https://example.com/?q=a%2Bb\u0026#34;) value := parsed.Query().Get(\u0026#34;q\u0026#34;) ❌ Confusing path and query decoding:\npath := url.QueryUnescape(\u0026#34;foo+bar%21\u0026#34;) // \u0026#34;+\u0026#34; becomes space ✅ Use PathUnescape for path segments:\npath, _ := url.PathUnescape(\u0026#34;foo+bar%21\u0026#34;) Best practices # Decode only the part you control (path vs query vs full URL). Use url.Parse for full URLs to avoid subtle encoding bugs. Expect multiple values per query key; use Get or iterate. Related topics # URL encode in Go - percent-encode path and query Join URL elements in Go - safe path assembly HTTP client timeout in Go - robust requests Print HTTP request and response in Go - inspect URLs and headers REST client in Go - complete request examples Tested with Go 1.25+ | Last verified: December 2025 🎉\n","date":"15 April 2021","permalink":"https://gosamples.dev/url-decode/","section":"Tutorials","summary":"","title":"How to URL-decode in Go with net/url (parse, query, path)"},{"content":"","date":null,"permalink":"https://gosamples.dev/categories/web/","section":"Categories","summary":"","title":"Web"},{"content":"URL encoding, also known as percent-encoding, makes URLs safe to transmit by encoding reserved characters. In Go, you handle this with the net/url package. ✅\nIn this guide, you will encode:\nquery parameters path segments a full URL and learn how to decode when needed What You\u0026rsquo;ll Learn # How to encode query parameters with url.QueryEscape and url.Values How to encode path segments with url.PathEscape How to build a full encoded URL safely How to decode values with QueryUnescape and PathUnescape A quick URL anatomy #scheme://host:port/path?query Encode the query part of the URL #The url.QueryEscape() function from the net/url package is used to encode a string placed inside a URL query.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { query1Val := url.QueryEscape(\u0026#34;ab+c\u0026#34;) query2Val := url.QueryEscape(\u0026#34;de$f\u0026#34;) fmt.Println(query1Val) fmt.Println(query2Val) } Output:\nab%2Bc de%24f To create an encoded multiple key-value query parameters string, use the url.Values structure from the net/url package.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { queryValues := url.Values{} queryValues.Add(\u0026#34;query\u0026#34;, \u0026#34;ab+c\u0026#34;) queryValues.Add(\u0026#34;query2\u0026#34;, \u0026#34;de$f\u0026#34;) encodedQuery := queryValues.Encode() fmt.Println(encodedQuery) } Output:\nquery=ab%2Bc\u0026amp;query2=de%24f Encode the path part of the URL #The url.PathEscape() function from the net/url package is used to encode a string that is placed inside a URL path segment. The path segment is encoded differently from the query, for example, the + character is allowed in the path, and should be encoded in the query.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { path := url.PathEscape(\u0026#34;foo+bar!\u0026#34;) fmt.Println(path) } Output:\nfoo+bar%21 Build a full encoded URL #There are two ways to construct a full encoded URL. You can create it manually by joining different parts of the URL, where the query and path parts are escaped with the previously used functions.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { // build url manually host := \u0026#34;https://example.com/\u0026#34; path := url.PathEscape(\u0026#34;foo+bar!\u0026#34;) query1Val := url.QueryEscape(\u0026#34;ab+c\u0026#34;) query2Val := url.QueryEscape(\u0026#34;de$f\u0026#34;) query := fmt.Sprintf(\u0026#34;query=%s\u0026amp;query2=%s\u0026#34;, query1Val, query2Val) fmt.Printf(\u0026#34;%s %s%s?%s\\n\u0026#34;, \u0026#34;Manually built URL:\u0026#34;, host, path, query) } Output:\nManually built URL: https://example.com/foo+bar%21?query=ab%2Bc\u0026amp;query2=de%24f However, it is generally better idea to build the encoded URL by using the url.URL structure. This way is easier and less error-prone than manually constructing the resulting URL. You just need to set the Scheme, Host, Path of the URL and build the RawQuery string by encoding query parameters inside the url.Values struct.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { // build url using url.URL struct exampleURL := \u0026amp;url.URL{ Scheme: \u0026#34;https\u0026#34;, Host: \u0026#34;example.com\u0026#34;, Path: \u0026#34;/foo+bar!\u0026#34;, } queryValues := url.Values{} queryValues.Add(\u0026#34;query\u0026#34;, \u0026#34;ab+c\u0026#34;) queryValues.Add(\u0026#34;query2\u0026#34;, \u0026#34;de$f\u0026#34;) exampleURL.RawQuery = queryValues.Encode() fmt.Printf(\u0026#34;%s %s\\n\u0026#34;, \u0026#34;URL built using url.URL struct:\u0026#34;, exampleURL) } URL built using url.URL struct: https://example.com/foo+bar%21?query=ab%2Bc\u0026amp;query2=de%24f Decode URL-encoded values (related utilities) #Use these when you need to read encoded values back:\nurl.QueryUnescape() for query parameters url.PathUnescape() for path segments package main import ( \u0026#34;fmt\u0026#34; \u0026#34;net/url\u0026#34; ) func main() { decodedQuery, _ := url.QueryUnescape(\u0026#34;ab%2Bc\u0026#34;) decodedPath, _ := url.PathUnescape(\u0026#34;foo+bar%21\u0026#34;) fmt.Println(decodedQuery) fmt.Println(decodedPath) } Output:\nab+c foo+bar! Common mistakes #❌ Using QueryEscape for a path segment:\npath := url.QueryEscape(\u0026#34;foo+bar!\u0026#34;) // \u0026#34;+\u0026#34; becomes \u0026#34;%2B\u0026#34; (not what you want) ✅ Use PathEscape for path segments:\npath := url.PathEscape(\u0026#34;foo+bar!\u0026#34;) ❌ Manually concatenating query strings without encoding:\nquery := \u0026#34;q=go+tips\u0026amp;tag=c#\u0026#34; ✅ Use url.Values:\nvalues := url.Values{} values.Add(\u0026#34;q\u0026#34;, \u0026#34;go+tips\u0026#34;) values.Add(\u0026#34;tag\u0026#34;, \u0026#34;c#\u0026#34;) query := values.Encode() Best practices # Use url.Values for query strings to avoid subtle encoding bugs. Use url.URL to assemble full URLs safely. Encode only the parts you control, not the entire URL string. Related topics # URL decode in Go - reverse percent-encoding Join URL elements in Go - safe path assembly HTTP client timeout in Go - robust requests Print HTTP request and response in Go - inspect URLs and headers REST client in Go - complete request examples Tested with Go 1.25+ | Last verified: December 2025 🎉\n","date":"13 April 2021","permalink":"https://gosamples.dev/url-encode/","section":"Tutorials","summary":"","title":"How to URL-encode in Go with net/url (query, path, full URL)"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/net-url/","section":"Tags","summary":"","title":"Net-Url"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/query/","section":"Tags","summary":"","title":"Query"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/duration/","section":"Tags","summary":"","title":"Duration"},{"content":"The time.Sleep function pauses the current goroutine for a specific duration. It is the simplest way to delay execution in Go and is built into the standard time package. ⏱️\nWhat is time.Sleep? #time.Sleep(d time.Duration) blocks the current goroutine for d. The duration is expressed as a number multiplied by a time unit, like 500*time.Millisecond or 2*time.Second.\nCommon units:\ntime.Nanosecond time.Microsecond time.Millisecond time.Second time.Minute time.Hour When to use time.Sleep #Use it for short, controlled delays such as:\nSimulating network latency in a demo Spacing out retries with a fixed delay Pacing log output in CLI tools How to pause execution with time.Sleep #This full program prints a message, sleeps for 3 seconds, and continues:\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func main() { fmt.Println(\u0026#34;before Sleep()\u0026#34;) time.Sleep(3 * time.Second) fmt.Println(\u0026#34;waking up after Sleep()\u0026#34;) } Common mistakes #❌ Using plain integers without a unit:\ntime.Sleep(3) // sleeps for 3 nanoseconds, not 3 seconds ✅ Always multiply by a time unit:\ntime.Sleep(3 * time.Second) ❌ Using time.Sleep to coordinate goroutines:\ntime.Sleep(100 * time.Millisecond) // unreliable synchronization ✅ Use channels, sync.WaitGroup, or context for coordination.\nBest practices # Keep delays explicit and small; prefer time.Duration variables for clarity. If you need timeouts, use context or time.Timer instead of hard sleeps. Document why the delay exists to avoid accidental removal. ✅ Related topics # Measure execution time in Go - time code blocks reliably Range over a ticker in Go - periodic work without manual sleeps Handle context deadline exceeded - timeouts with context HTTP client timeout in Go - timeouts for requests Convert time to string in Go - formatting time values Tested with Go 1.25+ | Last verified: December 2025 🎉\n","date":"12 April 2021","permalink":"https://gosamples.dev/sleep/","section":"Tutorials","summary":"","title":"How to use time.Sleep in Go (Golang) to pause execution"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/sleep/","section":"Tags","summary":"","title":"Sleep"},{"content":"In Go, there are several ways to check and print a variable\u0026rsquo;s type. Whether you need a quick type check during debugging or programmatic type inspection, Go provides simple and powerful tools.\nWhat You\u0026rsquo;ll Learn:\nPrint types using fmt.Printf with %T format Use reflection with reflect.TypeOf() Work with modern type reflection (Go 1.22+) Check types programmatically with type switches Let\u0026rsquo;s explore each method! 🚀\nMethod 1: Using %T Format Verb (Recommended) #The simplest way to print a variable\u0026rsquo;s type is using the %T verb in the fmt.Printf() function. This is the recommended approach for most cases.\npackage main import ( \u0026#34;fmt\u0026#34; ) func main() { t1 := \u0026#34;text\u0026#34; t2 := []string{\u0026#34;apple\u0026#34;, \u0026#34;strawberry\u0026#34;, \u0026#34;blueberry\u0026#34;} t3 := map[string]float64{\u0026#34;strawberry\u0026#34;: 3.2, \u0026#34;blueberry\u0026#34;: 1.2} t4 := 2 t5 := 4.5 t6 := true fmt.Printf(\u0026#34;t1: %T\\n\u0026#34;, t1) fmt.Printf(\u0026#34;t2: %T\\n\u0026#34;, t2) fmt.Printf(\u0026#34;t3: %T\\n\u0026#34;, t3) fmt.Printf(\u0026#34;t4: %T\\n\u0026#34;, t4) fmt.Printf(\u0026#34;t5: %T\\n\u0026#34;, t5) fmt.Printf(\u0026#34;t6: %T\\n\u0026#34;, t6) } Method 2: Using reflect.TypeOf() #You can also use the TypeOf() function from the reflect package to get type information. This is useful when you need to work with types programmatically.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;reflect\u0026#34; ) func main() { t1 := \u0026#34;text\u0026#34; t2 := []string{\u0026#34;apple\u0026#34;, \u0026#34;strawberry\u0026#34;, \u0026#34;blueberry\u0026#34;} t3 := map[string]float64{\u0026#34;strawberry\u0026#34;: 3.2, \u0026#34;blueberry\u0026#34;: 1.2} t4 := 2 t5 := 4.5 t6 := true fmt.Printf(\u0026#34;t1: %s\\n\u0026#34;, reflect.TypeOf(t1)) fmt.Printf(\u0026#34;t2: %s\\n\u0026#34;, reflect.TypeOf(t2)) fmt.Printf(\u0026#34;t3: %s\\n\u0026#34;, reflect.TypeOf(t3)) fmt.Printf(\u0026#34;t4: %s\\n\u0026#34;, reflect.TypeOf(t4)) fmt.Printf(\u0026#34;t5: %s\\n\u0026#34;, reflect.TypeOf(t5)) fmt.Printf(\u0026#34;t6: %s\\n\u0026#34;, reflect.TypeOf(t6)) } Both methods return the same output:\nt1: string t2: []string t3: map[string]float64 t4: int t5: float64 t6: bool Note: The reflect package uses runtime reflection which has some performance overhead. For simple type printing during debugging, use %T instead.\nMethod 3: Modern Type Reflection (Go 1.22+) #Starting with Go 1.22, you can use reflect.TypeFor[T]() to get type information for types known at compile time. This is cleaner and more type-safe than the old pattern.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;reflect\u0026#34; ) func main() { // Get type information using generics intType := reflect.TypeFor[int]() stringType := reflect.TypeFor[string]() sliceType := reflect.TypeFor[[]string]() mapType := reflect.TypeFor[map[string]int]() fmt.Println(\u0026#34;int type:\u0026#34;, intType) fmt.Println(\u0026#34;string type:\u0026#34;, stringType) fmt.Println(\u0026#34;slice type:\u0026#34;, sliceType) fmt.Println(\u0026#34;map type:\u0026#34;, mapType) // You can also use it with interfaces errorType := reflect.TypeFor[error]() fmt.Println(\u0026#34;error type:\u0026#34;, errorType) } Output:\nint type: int string type: string slice type: []string map type: map[string]int error type: error This replaces the old pattern of reflect.TypeOf((*SomeType)(nil)).Elem() with a much cleaner syntax.\nMethod 4: Type Switches and Kind() #When you need to check types programmatically (not just print them), you can use type switches or the Kind() method.\nUsing Type Switches #Type switches work with interface{} values to determine their underlying type:\npackage main import \u0026#34;fmt\u0026#34; func checkType(v interface{}) { switch v.(type) { case int: fmt.Println(\u0026#34;Type: int\u0026#34;) case string: fmt.Println(\u0026#34;Type: string\u0026#34;) case []string: fmt.Println(\u0026#34;Type: []string\u0026#34;) case map[string]int: fmt.Println(\u0026#34;Type: map[string]int\u0026#34;) default: fmt.Printf(\u0026#34;Type: %T\\n\u0026#34;, v) } } func main() { checkType(42) checkType(\u0026#34;hello\u0026#34;) checkType([]string{\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;}) checkType(map[string]int{\u0026#34;key\u0026#34;: 1}) checkType(3.14) } Output:\nType: int Type: string Type: []string Type: map[string]int Type: float64 Using reflect.Kind() #The Kind() method returns the specific kind of type (int, string, slice, map, etc.):\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;reflect\u0026#34; ) func main() { values := []interface{}{ 42, \u0026#34;hello\u0026#34;, []int{1, 2, 3}, map[string]int{\u0026#34;a\u0026#34;: 1}, true, } for _, v := range values { t := reflect.TypeOf(v) fmt.Printf(\u0026#34;Value: %v, Type: %v, Kind: %v\\n\u0026#34;, v, t, t.Kind()) } } Output:\nValue: 42, Type: int, Kind: int Value: hello, Type: string, Kind: string Value: [1 2 3], Type: []int, Kind: slice Value: map[a:1], Type: map[string]int, Kind: map Value: true, Type: bool, Kind: bool Quick Reference # Method Use Case Go Version %T with fmt.Printf() Quick debugging, simple type printing All versions reflect.TypeOf() Programmatic type inspection All versions reflect.TypeFor[T]() Compile-time known types with generics Go 1.22+ Type switches Conditional logic based on type All versions reflect.Kind() Get the underlying kind of a type All versions Related Topics #Here are some related Go tutorials you might find helpful:\nPrint Struct Variables - Learn different ways to print and format struct values Print Variable Address - How to print memory addresses of variables Format Cheatsheet - Complete guide to Go formatting verbs Type Assertions - Convert interface{} values to specific types Generics Cheatsheet - Learn about Go generics and type parameters Tested with Go 1.25+ | Last verified: December 2025\nHappy coding! 🎉\n","date":"6 April 2021","permalink":"https://gosamples.dev/print-type/","section":"Tutorials","summary":"","title":"Print Type of Variable in Go"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/reflect/","section":"Tags","summary":"","title":"Reflect"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/type/","section":"Tags","summary":"","title":"Type"},{"content":"Go doesn\u0026rsquo;t have a foreach keyword like other languages, but it has something even better - the for...range loop. This powerful construct lets you iterate over slices, arrays, maps, strings, channels, and even integers (since Go 1.22). It\u0026rsquo;s cleaner, safer, and more idiomatic than traditional C-style loops.\nIn this guide, you\u0026rsquo;ll learn all the ways to iterate in Go, including the latest features from Go 1.22+ that make loops safer and more expressive. 🔄\nBasic Range Syntax #Using the range keyword, you can create the range form of the for loop that is very useful when iterating over a slice or map. This kind of loop has the form of:\nfor \u0026lt;index\u0026gt;, \u0026lt;value\u0026gt; := range \u0026lt;array/slice\u0026gt; { ... } where:\n\u0026lt;index\u0026gt; is a numeric ordinal number that returns 0 for the first element in the array, 1 for the second, and so on \u0026lt;value\u0026gt; is a copy of a slice/array element at that \u0026lt;index\u0026gt; For maps, the for range loop has \u0026lt;key\u0026gt; instead of \u0026lt;index\u0026gt;:\nfor \u0026lt;key\u0026gt;, \u0026lt;value\u0026gt; := range \u0026lt;map\u0026gt; { ... } where:\n\u0026lt;key\u0026gt; is the key of a given map entry \u0026lt;value\u0026gt; is a copy of a map element at that \u0026lt;key\u0026gt; Basic Examples #Iterating Over Slices #In the following example, we iterate through a slice to print each element. We don\u0026rsquo;t need the index, so we ignore it using the blank identifier (underscore):\nfruits := []string{\u0026#34;apple\u0026#34;, \u0026#34;strawberry\u0026#34;, \u0026#34;raspberry\u0026#34;} for _, fruit := range fruits { fmt.Printf(\u0026#34;Fruit: %s\\n\u0026#34;, fruit) } Output:\nFruit: apple Fruit: strawberry Fruit: raspberry Iterating Over Maps #When iterating over maps, you get both the key and value:\nfruitColors := map[string]string{ \u0026#34;apple\u0026#34;: \u0026#34;green\u0026#34;, \u0026#34;strawberry\u0026#34;: \u0026#34;red\u0026#34;, \u0026#34;raspberry\u0026#34;: \u0026#34;pink\u0026#34;, } for fruit, color := range fruitColors { fmt.Printf(\u0026#34;%s color is %s\\n\u0026#34;, fruit, color) } Output:\napple color is green strawberry color is red raspberry color is pink Modern Go Features (Go 1.22+) #Go 1.22 introduced game-changing improvements to for loops that make your code cleaner and safer.\nRange Over Integers #Since Go 1.22, you can range directly over integers - no more for i := 0; i \u0026lt; n; i++!\n// Old way (still works) for i := 0; i \u0026lt; 5; i++ { fmt.Printf(\u0026#34;Iteration %d\\n\u0026#34;, i) } // New way (Go 1.22+) ✨ for i := range 5 { fmt.Printf(\u0026#34;Iteration %d\\n\u0026#34;, i) } Both output:\nIteration 0 Iteration 1 Iteration 2 Iteration 3 Iteration 4 This is especially useful for simple counting loops and makes the code more readable.\nLoop Variable Scoping (Important!) #Major improvement in Go 1.22: Loop variables are now per-iteration scoped. This fixes a common bug that plagued Go developers for years.\n// Before Go 1.22 - BUG! All goroutines would print the same value values := []int{1, 2, 3, 4, 5} for _, v := range values { go func() { fmt.Println(v) // Would often print 5, 5, 5, 5, 5 }() } // Go 1.22+ - FIXED! Each goroutine gets its own copy for _, v := range values { go func() { fmt.Println(v) // Correctly prints 1, 2, 3, 4, 5 }() } Note: If your go.mod has go 1.22 or later, this fix is automatically enabled. No code changes needed! 🎉\nRange Over Functions (Go 1.23+) #Go 1.23 introduced the ability to range over custom iterator functions:\n// Custom iterator that yields even numbers func evenNumbers(max int) func(yield func(int) bool) { return func(yield func(int) bool) { for i := 0; i \u0026lt; max; i += 2 { if !yield(i) { return } } } } // Use it like a regular range loop for num := range evenNumbers(10) { fmt.Println(num) // Prints: 0, 2, 4, 6, 8 } Common Mistakes #1. Assuming Map Iteration Order #Problem: Map iteration order is randomized for security reasons.\nm := map[string]int{\u0026#34;a\u0026#34;: 1, \u0026#34;b\u0026#34;: 2, \u0026#34;c\u0026#34;: 3} // ❌ Wrong - order is not guaranteed for k, v := range m { fmt.Println(k, v) // Order may vary between runs } // ✅ Correct - sort keys if you need consistent order keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { fmt.Println(k, m[k]) // Guaranteed alphabetical order } 2. Modifying Slice During Iteration #numbers := []int{1, 2, 3, 4, 5} // ❌ Dangerous - can skip elements or panic for i, num := range numbers { if num%2 == 0 { numbers = append(numbers[:i], numbers[i+1:]...) // Modifying while iterating } } // ✅ Correct - iterate backwards or use a separate result slice result := make([]int, 0, len(numbers)) for _, num := range numbers { if num%2 != 0 { result = append(result, num) } } 3. Forgetting Range Returns a Copy #type Person struct { Name string Age int } people := []Person{{\u0026#34;Alice\u0026#34;, 25}, {\u0026#34;Bob\u0026#34;, 30}} // ❌ Wrong - modifying a copy, original unchanged for _, p := range people { p.Age++ // This doesn\u0026#39;t modify the original slice } // ✅ Correct - use index to modify original for i := range people { people[i].Age++ } // ✅ Also correct - use pointer slice peoplePtr := []*Person{{\u0026#34;Alice\u0026#34;, 25}, {\u0026#34;Bob\u0026#34;, 30}} for _, p := range peoplePtr { p.Age++ // This modifies the original because p is a pointer } Performance Considerations #Use Index-Only Loops for Large Structs #When iterating over slices of large structs, use index-only iteration to avoid copying:\ntype LargeStruct struct { Data [1024]byte } items := make([]LargeStruct, 1000) // ❌ Slower - copies each struct for _, item := range items { // item is a copy of items[i] processStruct(item) } // ✅ Faster - no copies for i := range items { // items[i] is accessed directly processStruct(items[i]) } Range Over Strings is UTF-8 Aware #text := \u0026#34;Hello 世界\u0026#34; // Iterates over runes (UTF-8 code points), not bytes for i, r := range text { fmt.Printf(\u0026#34;Position %d: %c (Unicode: %U)\\n\u0026#34;, i, r, r) } Output:\nPosition 0: H (Unicode: U+0048) Position 1: e (Unicode: U+0065) Position 2: l (Unicode: U+006C) Position 3: l (Unicode: U+006C) Position 4: o (Unicode: U+006F) Position 5: (Unicode: U+0020) Position 6: 世 (Unicode: U+4E16) Position 9: 界 (Unicode: U+754C) Notice position 6 jumps to 9 because the Chinese characters are multi-byte.\nRelated Topics #Master other loop patterns and iteration techniques:\nWhile loop in Go - Simulate while loops using for Infinite loop - Create loops that run forever Do-while loop - Execute code at least once Break and continue - Control loop flow Range over ticker - Iterate with time intervals Tested with Go 1.25+ | Last verified: December 2025\nHappy iterating! 🚀\n","date":"26 March 2021","permalink":"https://gosamples.dev/foreach/","section":"Tutorials","summary":"","title":"Foreach Loop in Go: Range, Iterate, and Modern Patterns"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/range/","section":"Tags","summary":"","title":"Range"},{"content":"","date":null,"permalink":"https://gosamples.dev/tags/fmt/","section":"Tags","summary":"","title":"Fmt"},{"content":"What You\u0026rsquo;ll Learn #In this tutorial, you\u0026rsquo;ll write the classic \u0026ldquo;Hello World\u0026rdquo; program in Go - a simple program that displays \u0026ldquo;Hello World\u0026rdquo; on the screen. This is traditionally the first program written when learning any new programming language, and it\u0026rsquo;s the perfect way to verify your Go installation and understand the basic structure of a Go program.\nLet\u0026rsquo;s write your first Go program step by step! 🚀\nIf you don\u0026rsquo;t have Golang installed, visit the official Go website and install the version appropriate for your operating system.\nGolang \u0026ldquo;Hello World\u0026rdquo; program #Create hello-world directory #It is a good practice that each new project has its own directory.\nSave the following program as main.go in the hello-world directory #package main import \u0026#34;fmt\u0026#34; func main() { fmt.Println(\u0026#34;Hello World!\u0026#34;) } Run your program #$ go run hello-world/main.go Output\nHello World! Congratulations! You have just created your first program in Go \u0026#x1f680;.\nHow Golang \u0026ldquo;Hello World\u0026rdquo; program works #package main In Go, every program starts with a package declaration. A package is a collection of source files used to organize related code into a single unit. We are declaring a package called main here because we will need to declare the main() function, which can only be declared in a package named main.\nimport \u0026#34;fmt\u0026#34; Next, we have the package import statement. In our program, the fmt package has been imported and will be used in the main() function to print the \u0026ldquo;Hello World\u0026rdquo; text to the standard output (your screen).\nfunc main() { //... } The func main() starts the definition of the main() function. The main() is a special function that is executed first when the program starts. As you already know, the main() function in Go should always be declared in the main package.\nfmt.Println(\u0026#34;Hello World!\u0026#34;) The main() calls the Println() function of the fmt package. After starting the program, it prints the passed argument (our text \u0026ldquo;Hello World!\u0026rdquo;) to the standard output together with a new line.\nCommon Mistakes #When writing your first Go program, watch out for these common pitfalls:\n1. Wrong package name\npackage hello // ❌ Wrong - main() requires package main The main() function must be in a package named main, otherwise your program won\u0026rsquo;t compile.\n2. Missing or incorrect imports\nimport fmt // ❌ Wrong - missing quotes import \u0026#34;fmt\u0026#34; // ✅ Correct 3. Incorrect function name\nfunc Main() { // ❌ Wrong - capital M won\u0026#39;t be recognized fmt.Println(\u0026#34;Hello World!\u0026#34;) } Go is case-sensitive. The entry point must be main() with a lowercase \u0026rsquo;m'.\n4. Forgetting to save the file\nMake sure to save your main.go file before running go run!\nRelated Topics #Now that you\u0026rsquo;ve written your first Go program, explore these related tutorials:\nPrint struct variables - Learn different ways to display data Read user input - Make your programs interactive Environment variables - Access system configuration Exit codes - Control how your program terminates Tested with Go 1.25+ | Last verified: December 2025\nCongratulations on writing your first Go program! 🎉\n","date":"21 January 2021","permalink":"https://gosamples.dev/hello-world/","section":"Tutorials","summary":"","title":"Hello World in Go: Your First Program"},{"content":"","date":null,"permalink":"https://gosamples.dev/series/","section":"Series","summary":"","title":"Series"}]