From 02ef8fa5ddb8111aa8752ffb8267e67c4e209649 Mon Sep 17 00:00:00 2001
From: Steve Traut
@@ -73,16 +73,13 @@ func TestHelloEmpty(t *testing.T) {
Implement test functions in the same package as the code you're testing.
- This topic introduced Go's built-in support for unit testing. In the
- tutorial's next topic, you'll see how to
- compile and install your code to run it locally.
+ In the next (and last) topic, you'll see how to compile and install your code
+ to run it locally.
- In the previous section, you created a
+ In the previous section, you created a
- For example, if your current directory in the command prompt is the
- greetings directory, you could use the following commands:
+ After you create this directory, you should have both a hello and a
+ greetings directory at the same level in the hierarchy, like so:
+
+ For example, if your command prompt is in the greetings directory, you
+ could use the following commands:
+ To enable dependency tracking for your code, run the
+
+ For the purposes of this tutorial, use
In this code, you:
@@ -71,16 +99,16 @@ func main() {
- From the command line at the hello directory, run the
-
- For production use, you’d publish your modules on a server, either inside
- your company or on the internet, and the Go command will download them
- from there. For now, you need to adapt the caller's module so it can find
- the greetings code on your local file system.
+ For production use, you’d publish the
- To do that, make a small change to
+ The command specifies that
- Here, the
-
-
+ After the command completes, the
- To build the module, Go found the local code in the ../greetings
- directory, then added a
-
-
+ The number following the module path is a pseudo-version number
+ -- a generated number used in place of a semantic version number (which
+ the module doesn't have yet).
- To reference a published module, a go.mod file would omit the
- For more on version numbers, see
+ Module version numbering.
- Congrats! You've written two functioning modules. In the tutorial's
- next topic, you'll add some error handling.
+ Congrats! You've written two functioning modules.
+
+ In the next topic, you'll add some error handling.
- In the last section, you'll learn a new
+ This topic introduces two additional commands for building code:
- In the next step, you'll call this
- function from another module.
+ In the next step, you'll call this function from another module.
- When your code imports packages from another module, a go.mod file lists
- the specific modules and versions providing those packages. That file
- stays with your code, including in your source code repository.
+ When your code imports packages contained in other modules, you manage
+ those dependencies through your code's own module. That module is defined
+ by a go.mod file that tracks the modules that provide those packages. That
+ go.mod file stays with your code, including in your source code
+ repository.
- To create a go.mod file, run the
- For the purposes of this tutorial, just use
+
The
-
- Go will add the
With this quick introduction, you got Go installed and learned some of the
basics. To write some more code with another tutorial, take a look at
- Create a Go module.
+ Create a Go module.
In the last changes you'll make to your module's code, you'll add support for
getting greetings for multiple people in one request. In other words, you'll
- handle a multiple-value input and pair values with a multiple-value output.
+ handle a multiple-value input, then pair values in that input with a
+ multiple-value output. To do this, you'll need to pass a set of names to a
+ function that can return a greeting for each of them.
- To do this, you'll need to pass a set of names to a function that can return a
- greeting for each of them. Changing the greetings.Hello function. Test function names have the form
- TestName, where Name is specific to the test. Also, test functions
- take a pointer to the
- testing package's
- testing.T as a parameter. You use this parameter's methods
- for reporting and logging from your test.
+ Create two test functions to test the greetings.Hello
+ function. Test function names have the form TestName,
+ where Name says something about the specific test. Also, test
+ functions take a pointer to the testing package's
+ testing.T
+ type as a parameter. You use this parameter's methods for reporting
+ and logging from your test.
t parameter's
- Fatalf method to print a message to the console and end
- execution.
+
+ Fatalf method to print a message to the console
+ and end execution.
TestHelloEmpty calls the Hello function
with an empty string. This test is designed to confirm that your
error handling works. If the call returns a non-empty string or no
- error, you use the t parameter's
- Fatalf method
- to print a message to the console and end execution.
+ error, you use the t parameter's Fatalf
+ method to print a message to the console and end execution.
go test command
to execute the test.
@@ -202,16 +197,15 @@ FAIL example.com/greetings 0.182s
greetings module. In this section, you'll write code to make
calls to the Hello function in the module you just wrote. You'll
write code you can execute as an application, and which calls code in the
@@ -13,7 +13,7 @@
@@ -22,8 +22,16 @@
is where you'll write your caller.
<home>/
+ |-- greetings/
+ |-- hello/
+
+
@@ -35,7 +43,28 @@ cd hello
go mod init command, giving it the name of the module
+ your code will be in.example.com/hello
+ for the module path.
+
+$ go mod init example.com/hello
+go: creating new go.mod: module example.com/hello
+
+
@@ -248,12 +248,11 @@ message = fmt.Sprintf("Hi, %v. Welcome!", name)
main package. In Go, code executed as an
- application must go in a main package.
+ application must be in a main package.
example.com/greetings and
- fmt. This gives your code access to functions in those
- packages. Importing example.com/greetings (the package
- contained in the module you created earlier) gives you access to the
- Hello function. You also import fmt, with
- functions for handling input and output text (such as printing text to
- the console).
+ the fmt package. This
+ gives your code access to functions in those packages. Importing
+ example.com/greetings (the package contained in the module
+ you created earlier) gives you access to the Hello
+ function. You also import fmt, with functions for handling
+ input and output text (such as printing text to the console).
greetings package’s
@@ -90,148 +118,124 @@ func main() {
example.com/hello module to use your local
+ example.com/greetings module.
go mod init command, giving it the name of the module your
- code will be in (here, just use "hello").
-
-$ go mod init hello
-go: creating new go.mod: module hello
-
- hello module to use the unpublished greetings module.
-
- example.com/greetings
+ module from its repository (with a module path that reflected its published
+ location), where Go tools could find it to download it.
+ For now, because you haven't published the module yet, you need to adapt
+ the example.com/hello module so it can find the
+ example.com/greetings code on your local file system.
hello module’s go.mod
- file.
+ To do that, use the
+ go
+ mod edit command to edit the example.com/hello
+ module to redirect Go tools from its module path (where the module isn't)
+ to the local directory (where it is).
-
+$ go mod edit -replace=example.com/greetings=../greetings
+
+
+ example.com/greetings should be
+ replaced with ../greetings for the purpose of locating the
+ dependency. After you run the command, the go.mod file in the hello
+ directory should include a
+ replace directive:
+
-module hello
+module example.com/hello
-go 1.14
+go 1.16
replace example.com/greetings => ../greetings
-
- replace directive
-
- tells Go to replace the module path (the URL
- example.com/greetings) with a path you specify. In this
- case, that's a greetings directory next to the hello directory.
- go build to make Go locate the
- module and add it as a dependency to the go.mod file.
+ From the command prompt in the hello directory, run the
+
+ go mod tidy command to synchronize the
+ example.com/hello module's dependencies, adding those
+ required by the code, but not yet tracked in the module.
-
-$ go build
+
$ go mod tidy
go: found example.com/greetings in example.com/greetings v0.0.0-00010101000000-000000000000
-
- go build,
- including the require directive Go added.
+
+ example.com/hello
+ module's go.mod file should look like this:
+
-module hello
+
module example.com/hello
-go 1.14
+go 1.16
replace example.com/greetings => ../greetings
-require example.com/greetings v0.0.0-00010101000000-000000000000
-
+require example.com/greetings v0.0.0-00010101000000-000000000000require directive
-
- to specify that hello is dependent on (requires)
- example.com/greetings. You created this dependency when
- you imported the greetings package (contained in the
- greetings module) in hello.go. The replace directive
- tells Go where to find the greetings module, because it
- isn't published yet.
+ The command found the local code in the greetings directory, then
+ added a require
+ directive to specify that example.com/hello
+ requires example.com/greetings. You created this
+ dependency when you imported the greetings package in
+ hello.go.
+ replace directive and use a
- require directive with a tagged version number at the
- end.
+ To reference a published module, a go.mod file would
+ typically omit the replace directive and use a
+ require directive with a tagged version number at the end.
require example.com/greetings v1.1.0
+
+ hello directory, run the hello executable
- (created by go build) to confirm that the code works.
-
-
+
hello directory, run your code to
+ confirm that it works.
-
-$ ./hello
-Hi, Gladys. Welcome!
-
-
-$ hello.exe
+
+$ go run .
Hi, Gladys. Welcome!
-
- go command. While the
- go run command is a useful shortcut for compiling and running a
- single-file program, it doesn't generate a binary executable you can easily
- run again. If you want one of those, a good choice is to run the
- go install command, which compiles your code and installs the resulting binary executable where
- you can run it.
+ In this last topic, you'll learn a couple new go commands. While
+ the go run command is a useful shortcut for compiling and running
+ a program when you're making frequent changes, it doesn't generate a binary
+ executable.
+
+
go
+ build command compiles the packages, along with their dependencies,
+ but it doesn't install the results.
+ go
+ install command compiles and installs the packages.
+ Prerequisites
@@ -90,26 +90,35 @@ cd hello
go mod init command, giving it the name of the module your code will be in (here, just use
- "hello"):
+ To enable dependency tracking for your code by creating a go.mod file, run
+ the
+ go mod init command,
+ giving it the name of the module your code will be in. The name is the
+ module's module path. In most cases, this will be the repository
+ location where your source code will be kept, such as
+ github.com/mymodule. If you plan to publish your module
+ for others to use, the module path must be a location from
+ which Go tools can download your module.
+ example.com/hello.
-$ go mod init hello
-go: creating new go.mod: module hello
+$ go mod init example.com/hello
+go: creating new go.mod: module example.com/hello
fmt package,
+ fmt package,
which contains functions for formatting text, including printing to the
console. This package is one of the
- standard library packages you got
+ standard library packages you got
when you installed Go.
go run command
is one of many go commands you'll use to get things done with
@@ -252,7 +261,10 @@ func main() {
Add new module requirements and sums.
quote module as a requirement, as well as a go.sum file for use in authenticating the module. For more, see Module authentication using go.sum.
+ Go will add the quote module as a requirement, as well as a
+ go.sum file for use in authenticating the module. For more, see
+ Authenticating modules in the Go
+ Modules Reference.
$ go mod tidy
@@ -289,5 +301,5 @@ Don't communicate by sharing memory, share memory by communicating.
Hello function's
- parameter from a single name to a set of names would change the function
- signature. If you had already published the greetings module and
- users had already written code calling Hello, that change would
- break their programs. In this situation, a better choice is to give new
- functionality a new name.
-Hello function's
+ parameter from a single name to a set of names would change the function's
+ signature. If you had already published the example.com/greetings
+ module and users had already written code calling Hello, that
+ change would break their programs.
- In the last code you'll add with this tutorial, update the code as if you've
- already published a version of the greetings module. Instead of
- changing the Hello function, add a new function
- Hellos that takes a set of names. Then, for the sake of
- simplicity, have the new function call the existing one. Keeping both
- functions in the package leaves the original for existing callers (or future
- callers who only need one greeting) and adds a new one for callers that want
- the expanded functionality.
+ In this situation, a better choice is to write a new function with a different
+ name. The new function will take multiple parameters. That preserves the old
+ function for backward compatibility.
Hellos function call the existing
+ Hello function. This helps reduce duplication while also
+ leaving both functions in place.
messages
- map to associate each of the
+ Create a messages map to associate each of the
received names (as a key) with a generated message (as a value). In Go,
you initialize a map with the following syntax:
make(map[key-type]value-type). You have
- the Hellos function return this map to the caller.
+ the Hellos function return this map to the caller. For more
+ about maps, see Go maps in
+ action on the Go blog.
for loop, range returns two values: the index
of the current item in the loop and a copy of the item's value. You
- don't need the index, so you use the Go
- blank identifier (an underscore)
- to ignore it.
+ don't need the index, so you use the Go blank identifier (an underscore)
+ to ignore it. For more, see
+ The blank
+ identifier in Effective Go.
go run to confirm that the code works.
The output should be a string representation of the map associating names @@ -201,7 +196,7 @@ func main() {
-$ go run hello.go +$ go run . map[Darrin:Hail, Darrin! Well met! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Samantha! Well met!]@@ -210,18 +205,18 @@ map[Darrin:Hail, Darrin! Well met! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Sa
This topic introduced maps for representing name/value pairs. It also - introduced the idea of - preserving backward compatibility + introduced the idea of preserving backward compatibility by implementing a new function for new or changed functionality in a module. - In the tutorial's next topic, you'll use - built-in features to create a unit test for your code. + For more about backward compatibility, see + Keeping your modules + compatible.
+Next, you'll use built-in Go features to create a unit test for your code.
+ diff --git a/_content/doc/tutorial/handle-errors.html b/_content/doc/tutorial/handle-errors.html index 4dfd4b13..76f7a4f3 100644 --- a/_content/doc/tutorial/handle-errors.html +++ b/_content/doc/tutorial/handle-errors.html @@ -11,7 +11,7 @@string and an error. Your caller will check
the second value to see if an error occurred. (Any Go function can
- return multiple values.)
+ return multiple values. For more, see
+ Effective Go.)
errors package so you can
use its
- errors.New function.
log package to
+ log package to
print the command name ("greetings: ") at the start of its log messages,
without a time stamp or source file information.
-$ go run hello.go +$ go run . greetings: empty name exit status 1
- That's essentially how error handling in Go works: Return an error as a value - so the caller can check for it. It's pretty simple. In the tutorial's - next topic, you'll use a Go slice to return - a randomly-selected greeting. + That's common error handling in Go: Return an error as a value so the caller + can check for it. +
+ ++ Next, you'll use a Go slice to return a randomly-selected greeting.
diff --git a/_content/doc/tutorial/index.html b/_content/doc/tutorial/index.html index 80f9c018..1bbb78d0 100644 --- a/_content/doc/tutorial/index.html +++ b/_content/doc/tutorial/index.html @@ -20,13 +20,13 @@+ In this tutorial, you wrote functions that you packaged into two modules: one + with logic for sending greetings; the other as a consumer for the first. +
+ ++ For more on managing dependencies in your code, see + Managing dependencies. For + more about developing modules for others to use, see + Developing and publishing modules. +
+ +For many more features of the Go language, check out the + Tour of Go. +
+ + diff --git a/_content/doc/tutorial/random-greeting.html b/_content/doc/tutorial/random-greeting.html index d5a45be6..c6c8da72 100644 --- a/_content/doc/tutorial/random-greeting.html +++ b/_content/doc/tutorial/random-greeting.html @@ -10,15 +10,20 @@- To do this, you'll use a Go slice. A - slice is like an - array, except that it's dynamically sized as you add and remove items. It's - one of the most useful types in Go. You'll add a small slice to contain three - greeting messages, then have your code return one of the messages randomly. + To do this, you'll use a Go slice. A slice is like an array, except that its + size changes dynamically as you add and remove items. The slice is one of Go's + most useful types. +
+ ++ You'll add a small slice to contain three greeting messages, then have your + code return one of the messages randomly. For more on slices, + see Go slices in the Go + blog.
randomFormat, declare a formats slice with
three message formats. When declaring a slice, you omit its size in the
- brackets, like this: []string. This tells Go that the array
- underlying a slice can be dynamically sized.
+ brackets, like this: []string. This tells Go that the size
+ of the array underlying the slice can be dynamically changed.
math/rand package
to generate a random number for selecting an item from the slice.
init function
- to seed the rand package with the current time. Go executes
- init functions automatically at program startup, after
- global variables have been initialized.
+ Add an init function to seed the rand package
+ with the current time. Go executes init functions
+ automatically at program startup, after global variables have been
+ initialized. For more about init functions, see
+ Effective Go.
Hello, call the randomFormat function to
@@ -109,48 +112,70 @@ func randomFormat() string {
- Your hello.go needn't change. -
- Oh -- don't forget to add Gladys's name (or a different name, if you like)
- as an argument to the Hello function call in hello.go:
- greetings.Hello("Gladys")
-
You're just adding Gladys's name (or a different name, if you like)
+ as an argument to the Hello function call in hello.go.
package main
+
+import (
+ "fmt"
+ "log"
+
+ "example.com/greetings"
+)
+
+func main() {
+ // Set properties of the predefined Logger, including
+ // the log entry prefix and a flag to disable printing
+ // the time, source file, and line number.
+ log.SetPrefix("greetings: ")
+ log.SetFlags(0)
+
+ // Request a greeting message.
+ message, err := greetings.Hello("Gladys")
+ // If an error was returned, print it to the console and
+ // exit the program.
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // If no error was returned, print the returned message
+ // to the console.
+ fmt.Println(message)
+}
+ -$ go build -$ ./hello +$ go run . Great to see you, Gladys! -$ ./hello +$ go run . Hi, Gladys. Welcome! -$ ./hello +$ go run . Hail, Gladys! Well met! -+
- That's an introduction to a Go slice. To get even more use out of this type, - you'll use a slice to greet multiple people. That's in the tutorial's - next topic. + Next, you'll use a slice to greet multiple people.
-- cgit v1.3-5-g9baa