From 1d5af1553c91d346e70c83aa5b7132e242c15242 Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Thu, 4 Mar 2010 12:56:08 +1100 Subject: [PATCH] First run at a Programming FAQ Moved a couple of FAQs from the main FAQ, and added some others R=r, rsc, iant, gri CC=golang-dev https://golang.org/cl/218070 --- doc/go_faq.html | 61 +------- doc/go_programming_faq.html | 271 ++++++++++++++++++++++++++++++++++++ lib/godoc/godoc.html | 1 + 3 files changed, 277 insertions(+), 56 deletions(-) create mode 100644 doc/go_programming_faq.html diff --git a/doc/go_faq.html b/doc/go_faq.html index 9205c4507e..ff096ec9c3 100644 --- a/doc/go_faq.html +++ b/doc/go_faq.html @@ -79,15 +79,15 @@ the C and C++ languages themselves. We felt a viable solution required a more complete approach.

-Why doesn't Go run on Windows?

+Why doesn't Go run on Windows yet?

We understand that a significant fraction of computers in the world run Windows and it would be great if those computers could run Go -programs. However, the Go team is small and we don't have the -resources to do a Windows port at the moment. We would be -more than willing to answer questions and offer advice to anyone -willing to develop a Windows version. +programs. A group of volunteers has made significant progress toward +porting Go to MinGW. +You can follow their progress on the +mailing list.

@@ -220,26 +220,6 @@ How do I get dynamic dispatch of methods?

The only way to have dynamically dispatched methods is through an interface. Methods on structs or other types are always resolved statically. -

Concurrent programming

- -

-What operations are atomic? What about mutexes?

- -

-We haven't fully defined it all yet, but some details about atomicity are available in the -Go Memory Model specification. -Also, some concurrency questions are answered in more detail in the -language design FAQ. - -

-Regarding mutexes, the sync -package implements them, but we hope Go programming style will -encourage people to try higher-level techniques. In particular, consider -structuring your program so that only one goroutine at a time is ever -responsible for a particular piece of data. - -

-Do not communicate by sharing memory. Instead, share memory by communicating.

Writing Code

@@ -279,37 +259,6 @@ See the document Contributing to the Go project for more information about how to proceed. -

-How do I create a multifile package?

- -

-Put all the source files for the package in a directory by themselves. -Source files can refer to items from different files at will; there is -no header file or need for forward declarations. - -

-Other than being split into multiple files, the package will compile and test -just like a single-file package. - -

-How do I write a unit test?

- -

-Create a new file ending in _test.go in the same directory -as your package sources. Inside that file, import "testing" -and write functions of the form - -

-func TestFoo(t *testing.T) {
-    ...
-}
-
- -

-Run gotest in that directory. -That script finds the Test functions, -builds a test binary, and runs it. -

Where is assert?

diff --git a/doc/go_programming_faq.html b/doc/go_programming_faq.html new file mode 100644 index 0000000000..ecb64983c7 --- /dev/null +++ b/doc/go_programming_faq.html @@ -0,0 +1,271 @@ + + +

Pointers and Allocation

+ +

+When are function paramters passed by value?

+ +

+Everything in Go is passed by value. A function always gets a copy of the +thing being passed, as if there were an assignment statement assigning the +value to the parameter. For instance, copying a pointer value makes a copy of +the pointer, not the data it points to. +

+ +

+Map and slice values behave like pointers; they are descriptors that +contain pointers to the underlying map or slice data. Copying a map or +slice value doesn't copy the data it points to. Copying an interface value +makes a copy of the thing stored in the interface value. If the interface +value holds a struct, copying the interface value makes a copy of the +struct. If the interface value holds a pointer, copying the interface value +makes a copy of the pointer, but again not the data it points to. +

+ +

+Should I define methods on values or pointers?

+ +
+func (s *MyStruct) someMethod() { } // method on pointer
+func (s MyStruct) someMethod() { }  // method on value
+
+ +

+When defining a method on a type, the receiver (s in the above +example) behaves exactly is if it were an argument to the method. Define the +method on a pointer type if you need the method to modify the data the receiver +points to. Otherwise, it is often cleaner to define the method on a value type. +

+ +

+What's the difference between new and make?

+ +

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

+ +

+See the relevant section +of Effective Go for more details. +

+ +

+Why is int 32 bits on 64 bit machines?

+ +

+The size of int and float is implementation-specific. +The 64 bit Go compilers (both 6g and gccgo) use a 32 bit representation for +both int and float. Code that relies on a particular +size of value should use an explicitly sized type, like int64 or +float64. +

+ +

Concurrent programming

+ +

+What operations are atomic? What about mutexes?

+ +

+We haven't fully defined it all yet, but some details about atomicity are +available in the Go Memory Model specification. +Also, some concurrency questions are answered in more detail in the language design FAQ. +

+ +

+Regarding mutexes, the sync +package implements them, but we hope Go programming style will +encourage people to try higher-level techniques. In particular, consider +structuring your program so that only one goroutine at a time is ever +responsible for a particular piece of data. +

+ +

+Do not communicate by sharing memory. Instead, share memory by communicating. +

+ +

+Why doesn't my multi-goroutine program use multiple CPUs?

+ +

+Under the gc compilers you must set GOMAXPROCS to allow the +runtime to utilise more than one OS thread. Under gccgo an OS +thread will be created for each goroutine, and GOMAXPROCS is +effectively equal to the number of running goroutines. +

+ +

+Programs that perform concurrent computation should benefit from an increase in +GOMAXPROCS. (See the runtime package +documentation.) +

+ +

+Why does using GOMAXPROCS > 1 sometimes make my program +slower?

+ +

+(This is specific to the gc compilers. See above.) +

+ +

+It depends on the nature of your program. +Programs that contain several goroutines that spend a lot of time +communicating on channels will experience performance degradation when using +multiple OS threads. This is because of the significant context-switching +penalty involved in sending data between threads. +

+ +

+The Go runtime's scheduler is not as good as it needs to be. In future, it +should recognise such cases and optimize its use of OS threads. For now, +GOMAXPROCS should be set on a per-application basis. +

+ + +

Closures

+ +

+Why am I confused by the way my closures behave as goroutines?

+ +

+Some confusion may arise when using closures with concurrency. +Consider the following program: +

+ +
+func main() {
+	done := make(chan bool)
+
+	values = []string{ "a", "b", "c" }
+	for _, v := range values {
+		go func() {
+			fmt.Println(v)
+			done <- true
+		}()
+	}
+
+	// wait for all goroutines to complete before exiting
+	for i := range values {
+		<-done 
+	}
+}
+
+ +

+One might mistakenly expect to see a, b, c as the output. +What you'll probably see instead is c, c, c. This is because +each closure shares the same variable v. Each closure prints the +value of v at the time fmt.Println is executed, +rather than the value of v when the goroutine was launched. +

+ +

+To bind the value of v to each closure as they are launched, one +could modify the inner loop to read: +

+ +
+	for _, v := range values {
+		go func(u) {
+			fmt.Println(u)
+			done <- true
+		}(v)
+	}
+
+ +

+In this example, the value of v is passed as an argument to the +anonymous function. That value is then accessible inside the function as +the variable u. +

+ +

Control flow

+ +

+Does Go have the ?: operator?

+ +

+There is no ternary form in Go. You may use the following to achieve the same +result: +

+ +
+if expr {
+	n = trueVal
+} else {
+	n = falseVal
+}
+
+ +

Packages and Testing

+ +

+How do I create a multifile package?

+ +

+Put all the source files for the package in a directory by themselves. +Source files can refer to items from different files at will; there is +no need for forward declarations or a header file. +

+ +

+Other than being split into multiple files, the package will compile and test +just like a single-file package. +

+ +

+How do I write a unit test?

+ +

+Create a new file ending in _test.go in the same directory +as your package sources. Inside that file, import "testing" +and write functions of the form +

+ +
+func TestFoo(t *testing.T) {
+    ...
+}
+
+ +

+Run gotest in that directory. +That script finds the Test functions, +builds a test binary, and runs it. +

+ + +

Data Structures

+ +

Why does the syntax for nested array literals seem overly verbose?

+ +

+In Go, you must specify a 2-dimensional array literal like this: +

+ +
+var intArray = [4][4]int{
+	[4]int{1, 2, 3, 4},
+	[4]int{2, 4, 8, 16},
+	[4]int{3, 9, 27, 81},
+	[4]int{4, 16, 64, 256},
+}
+
+ +

+It seems that the [4]int could be inferred, but in general it's +hard to get this sort of thing right. +

+ +

+Some of Go's designers had worked on other languages that derived types +automatically in such expressions, but the special cases that arise can +be messy, especially when interfaces, nil, constant conversions, and +such are involved. It seemed better to require the full type +information. That way there will be no surprises. +

+ diff --git a/lib/godoc/godoc.html b/lib/godoc/godoc.html index b404857ebc..49902ff106 100644 --- a/lib/godoc/godoc.html +++ b/lib/godoc/godoc.html @@ -83,6 +83,7 @@
  • Effective Go
  • FAQ
  • Language Design FAQ
  • +
  • Programming FAQ
  • Tech talk (1 hour) (PDF)
  • Language Specification
  • Memory Model
  • -- 2.50.0