From f7b05a08b8e7fb79e7b4ca75d530deb198ac1f5c Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Sat, 14 Jul 2018 14:52:31 +1000 Subject: [PATCH] doc: update Values, Writing Code, and Pointers and Allocation sections of the FAQ Significant surgery done to the Versioning section, bringing it closer to modern thinking. Also add a question about constants. Update #26107. Change-Id: Icf70b7228503c6baaeab0b95ee3e6bee921575aa Reviewed-on: https://go-review.googlesource.com/123918 Reviewed-by: Ian Lance Taylor --- doc/go_faq.html | 126 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 40 deletions(-) diff --git a/doc/go_faq.html b/doc/go_faq.html index 4b3c48c5ff..c47c594b1d 100644 --- a/doc/go_faq.html +++ b/doc/go_faq.html @@ -953,6 +953,7 @@ and implementation.

Why does Go not provide implicit numeric conversions?

+

The convenience of automatic conversion between numeric types in C is outweighed by the confusion it causes. When is an expression unsigned? @@ -974,6 +975,43 @@ type is generic; if you care about how many bits an integer holds, Go encourages you to be explicit.

+

+How do constants work in Go?

+ +

+Although Go is strict about conversion between variables of different +numeric types, constants in the language are much more flexible. +Literal constants such as 23, 3.14159 +and math.Pi +occupy a sort of ideal number space, with arbitrary precision and +no overflow or underflow. +For instance, the value of math.Pi is specified to 63 places +in the source code, and constant expressions involving the value keep +precision beyond what a float64 could hold. +Only when the constant or constant expression is assigned to a +variable—a memory location in the program—does +it become a "computer" number with +the usual floating-point properties and precision. +

+ +

+Also, +because they are just numbers, not typed values, constants in Go can be +used more freely than variables, thereby softening some of the awkwardness +around the strict conversion rules. +One can write expressions such as +

+ +
+sqrt2 := math.Sqrt(2)
+
+ +

+without complaint from the compiler because the ideal number 2 +can be converted safely and accurately +to a float64 for the call to math.Sqrt. +

+

A blog post titled Constants explores this topic in more detail. @@ -1028,8 +1066,9 @@ How are libraries documented?

There is a program, godoc, written in Go, that extracts -package documentation from the source code. It can be used on the -command line or on the web. An instance is running at +package documentation from the source code and serves it as a web +page with links to declarations, files, and so on. +An instance is running at golang.org/pkg/. In fact, godoc implements the full site at golang.org/. @@ -1052,14 +1091,20 @@ subcommand that provides a textual interface to the same information. Is there a Go programming style guide?

-Eventually, there may be a small number of rules to guide things -like naming, layout, and file organization. +There is no explicit style guide, although there is certainly +a recognizable "Go style". +

+ +

+Go has established conventions to guide decisions around +naming, layout, and file organization. The document Effective Go -contains some style advice. +contains some advice on these topics. More directly, the program gofmt is a pretty-printer whose purpose is to enforce layout rules; it replaces the usual compendium of do's and don'ts that allows interpretation. -All the Go code in the repository has been run through gofmt. +All the Go code in the repository, and the vast majority in the +open source world, has been run through gofmt.

@@ -1123,11 +1168,25 @@ add these lines to your ~/.gitconfig: How should I manage package versions using "go get"?

-"Go get" does not have any explicit concept of package versions. +Since the inception of the project, Go has had no explicit concept of package versions, +but that is changing. Versioning is a source of significant complexity, especially in large code bases, -and we are unaware of any approach that works well at scale in a large enough -variety of situations to be appropriate to force on all Go users. -What "go get" and the larger Go toolchain do provide is isolation of +and it has taken some time to develop an +approach that works well at scale in a large enough +variety of situations to be appropriate to supply to all Go users. +

+ +

+The Go 1.11 release adds new, experimental support +for package versioning to the go command, +in the form of Go modules. +For more information, see the Go 1.11 release notes +and the go command documentation. +

+ +

+Regardless of the actual package management technology, +"go get" and the larger Go toolchain does provide isolation of packages with different import paths. For example, the standard library's html/template and text/template coexist even though both are "package template". @@ -1139,35 +1198,21 @@ Packages intended for public use should try to maintain backwards compatibility The Go 1 compatibility guidelines are a good reference here: don't remove exported names, encourage tagged composite literals, and so on. If different functionality is required, add a new name instead of changing an old one. -If a complete break is required, create a new package with a new import path.

- -

-If you're using an externally supplied package and worry that it might change in -unexpected ways, the simplest solution is to copy it to your local repository. -(This is the approach Google takes internally.) -Store the copy under a new import path that identifies it as a local copy. -For example, you might copy "original.com/pkg" to "you.com/external/original.com/pkg". -The gomvpkg -program is one tool to help automate this process. +If a complete break is required, create a new package with a new import path.

-The Go 1.5 release added a facility to the -go command -that makes it easier to manage external dependencies by "vendoring" -them into a special directory near the package that depends upon them. +If you're using an externally supplied package and worry that it might change in +unexpected ways, but are not yet using Go modules, +the simplest solution is to copy it to your local repository. +This is the approach Google takes internally and is supported by the +go command through a technique called "vendoring". +This involves +storing a copy of the dependency under a new import path that identifies it as a local copy. See the design document for details.

-

-The Go 1.11 release added new, experimental support -for package versioning to the go command, -in the form of Go modules. -For more information, see the Go 1.11 release notes -and the go command documentation. -

-

Pointers and Allocation

@@ -1209,7 +1254,7 @@ disguising an interface value's type for delayed evaluation.

-It is however a common mistake to pass a pointer to an interface value +It is a common mistake to pass a pointer to an interface value to a function expecting an interface. The compiler will complain about this error but the situation can still be confusing, because sometimes a pointer @@ -1285,9 +1330,10 @@ of passing a value), so changes it makes will be invisible to the caller.

-By the way, pointer receivers are identical to the situation in Java, -although in Java the pointers are hidden under the covers; it's Go's -value receivers that are unusual. +By the way, in Java method receivers are always pointers, +although their pointer nature is somewhat disguised +(and there is a proposal to add value receivers to the language). +It is the value receivers in Go that are unusual.

@@ -1315,7 +1361,7 @@ requires a pointer, a value receiver is efficient and clear. What's the difference between new and make?

-In short: new allocates memory, make initializes +In short: new allocates memory, while make initializes the slice, map, and channel types.

@@ -1332,9 +1378,9 @@ The sizes of int and uint are implementation-specific but the same as each other on a given platform. For portability, code that relies on a particular size of value should use an explicitly sized type, like int64. -Prior to Go 1.1, the 64-bit Go compilers (both gc and gccgo) used -a 32-bit representation for int. As of Go 1.1 they use -a 64-bit representation. +On 32-bit machines the compilers use 32-bit integers by default, +while on 64-bit machines integers have 64 bits. +(Historically, this was not always true.)

-- 2.50.0