diff --git a/doc/go_for_cpp_programmers.html b/doc/go_for_cpp_programmers.html index d6d4329ba81..ccd7db56269 100644 --- a/doc/go_for_cpp_programmers.html +++ b/doc/go_for_cpp_programmers.html @@ -34,23 +34,25 @@ There is more documentation about go. use a pointer variable to walk through the bytes of a string.
var
,
const
, or type
. Method declarations are a minor
exception in that
the receiver appears before the name of the object begin declared; see
-the discussion of interfaces.
+the discussion of interfaces.
You can also use a keyword followed by a series of declarations in @@ -108,7 +110,7 @@ var (i int; m float)
-When declaring a function, you must provide a name for each parameter +When declaring a function, you must either provide a name for each parameter or not provide a name for any parameter; you can't omit some names and provide others. You may group several names with the same type: @@ -174,24 +176,15 @@ always permitted at the end of a statement, so you can continue using them as in C++.
-Go treats semicolons as separators, not terminators. Moreover,
-a semicolon
-is not required after a curly brace ending a type declaration (e.g.,
-var s struct {}
) or a block. Semicolons are never required at the
-top level of a file (between global declarations). However, they are
-always permitted at
-the end of a statement, so you can continue using them as in C++.
-
-
-When using a pointer, you use .
instead of ->
.
-Thus syntactically
-speaking there is no difference between a structure and a pointer to a
-structure.
+When using a pointer to a struct, you use .
instead
+of ->
.
+Thus syntactically speaking a structure and a pointer to a structure
+are used in the same way.
-type my_struct struct { i int } -var v9 my_struct; // v9 has structure type -var p9 *my_struct; // p9 is a pointer to a structure +type myStruct struct { i int } +var v9 myStruct; // v9 has structure type +var p9 *myStruct; // p9 is a pointer to a structure f(v9.i, p9.i)@@ -238,10 +231,10 @@ switch i { case 0, 1: f() } // f is called if i == 0 || i == 1.
-The values in a case
need not be constants - or even integers;
+The values in a case
need not be constants—or even integers;
any type
that supports the equality comparison operator, such as strings or
-pointers, can be used - and if the switch
+pointers, can be used—and if the switch
value is omitted it defaults to true
.
@@ -254,6 +247,15 @@ statements, not in expressions. You cannot writec = *p++
.*p++
is parsed as(*p)++
. ++The
defer
statement may be used to call a function after +the function containing thedefer
statement returns. + ++fd := open("filename"); +defer close(fd); // fd will be closed when this function returns. ++Constants
@@ -292,8 +294,11 @@ const ( red = iota; blue; green ) // red == 0, blue == 1, green == 2
Slices
-A slice is a pointer to an array, a length, and a capacity. Slices support -the
[]
operator to access elements. The builtin +A slice is conceptually a struct with three fields: a +pointer to an array, a length, and a capacity. +Slices support +the[]
operator to access elements of the underlying array. +The builtinlen
function returns the length of the slice. The builtincap
function returns the capacity. @@ -383,82 +388,100 @@ entirely separate from the interface itself.A method looks like an ordinary function definition, except that it -has a receiver. The receiver is similar to the
this
pointer in a -C++ class method. +has a receiver. The receiver is similar to +thethis
pointer in a C++ class method.-type my_type struct { i int } -func (p *my_type) get() int { return p.i } +type myType struct { i int } +func (p *myType) get() int { return p.i }-This declares a method
get
associated withmy_type
. +This declares a methodget
associated withmyType
. The receiver is namedp
in the body of the function. ++Methods are defined on named types. If you convert the value +to a different type, the new value will have the methods of the new type, +not the old type. + +
+You may define methods on a builtin type by declaring a new named type +derived from it. The new type is distinct from the builtin type. + +
+type myInteger int +func (p myInteger) get() int { return int(p) } // Conversion required. +func f(i int) { } +var v myInteger +// f(v) is invalid. +// f(int(v)) is valid; int(v) has no defined methods. ++Given this interface:
-type my_interface interface { - get() int; - set(i int); +type myInterface interface { + get() int; + set(i int); }-we can make
my_type
satisfy the interface by additionally writing +we can makemyType
satisfy the interface by additionally writing-func (p *my_type) set(i int) { p.i = i } +func (p *myType) set(i int) { p.i = i }-Now any function which takes
my_interface
as a parameter +Now any function which takesmyInterface
as a parameter will accept a -variable of type*my_type
. +variable of type*myType
.-func get_and_set(x my_interface); +func getAndSet(x myInterface); func f1() { - var p my_type; - get_and_set(&p); + var p myType; + getAndSet(&p); }-In other words, if we view
my_interface
as a C++ pure abstract +In other words, if we viewmyInterface
as a C++ pure abstract base class, definingset
andget
for -*my_type
made*my_type
automatically -inherit frommy_interface
. A type may satisfy multiple interfaces. +*myType
made*myType
automatically +inherit frommyInterface
. A type may satisfy multiple interfaces.An anonymous field may be used to implement something much like a C++ child class.
-type my_child_type struct { my_type; j int } -func (p *my_child_type) get() int { p.j++; return (&p.my_type).get() } +type myChildType struct { myType; j int } +func (p *myChildType) get() int { p.j++; return (&p.myType).get() }-This effectively implements
my_child_type
as a child of -my_type
. +This effectively implementsmyChildType
as a child of +myType
.func f2() { - var p my_child_type; - get_and_set(&p) + var p myChildType; + getAndSet(&p) }The
set
method is effectively inherited from -my_child_type
, because +myChildType
, because methods associated with the anonymous type are promoted to become methods -of the enclosing type. In this case, becausemy_child_type
has an -anonymous field of typemy_type
, the methods of -my_type
also become methods ofmy_child_type
. +of the enclosing type. In this case, becausemyChildType
has an +anonymous field of typemyType
, the methods of +myType
also become methods ofmyChildType
. In this example, theget
method was overridden, and theset
method was inherited. @@ -478,23 +501,23 @@ at runtime, like C++dynamic_cast
. Unlike not need to be any declared relationship between the two interfaces.-type my_compare_interface interface { +type myCompareInterface interface { print(); } -func f3(x my_interface) { - x.(my_compare_interface).print() +func f3(x myInterface) { + x.(myCompareInterface).print() }-The conversion to
my_compare_interface
is entirely dynamic. +The conversion tomyCompareInterface
is entirely dynamic. It will -work as long as the underlying type of x (the "dynamic type") defines +work as long as the underlying type of x (the dynamic type) defines aBecause the conversion is dynamic, it may be used to implement generic -programming similar to templates in C++. This is done by, e.g., +programming similar to templates in C++. This is done by manipulating values of the minimal interface.
@@ -510,19 +533,26 @@ at runtime, but all operations will involve a function call.type iterator interface { - get() Any; - set(v Any); - increment(); - equal(arg *iterator) bool; + get() Any; + set(v Any); + increment(); + equal(arg *iterator) bool; }-Processes
+Goroutines
-Go permits starting a new process (a "goroutine") using the
go
-statement. The go statement runs a function in a different process. -All processes in a single program share the same address space. +Go permits starting a new thread of execution (a goroutine) +using thego
+statement. Thego
statement runs a function in a +different, newly created, goroutine. +All goroutines in a single program share the same address space. + ++Internally, goroutines act like coroutines that are multiplexed among +multiple operating system threads. You do not have to worry +about these details.
func server(i int) { for { print(i); sys.sleep(10) } } @@ -534,7 +564,7 @@ go server(1); go server(2); function is equivalent to a C++while (true)
loop).-Processes are (intended to be) cheap. +Goroutines are (intended to be) cheap.
Function literals can be useful with the
go
statement. @@ -542,16 +572,16 @@ Function literals can be useful with thego
statement.var g int // global variable go func(i int) { - s := 0 - for j := 0; j < i; j++ { s += j } - g = s + s := 0 + for j := 0; j < i; j++ { s += j } + g = s } (1000) // Passes argument 1000 to the function literal.Channels
-Channels are used to communicate between processes. Any value may be +Channels are used to communicate between goroutines. Any value may be sent over a channel. Channels are (intended to be) efficient and cheap. To send a value on a channel, use
<-
as a binary operator. To @@ -561,38 +591,38 @@ functions, channels are passed by reference.The Go library provides mutexes, but you can also use -a single process with a shared channel. +a single goroutine with a shared channel. Here is an example of using a manager function to control access to a single value.
type cmd struct { get bool; val int } func manager(ch chan cmd) { - var val int = 0; - for { - c := <- ch - if c.get { c.val = val; ch <- c } - else { val = c.val } - } + var val int = 0; + for { + c := <- ch + if c.get { c.val = val; ch <- c } + else { val = c.val } + } }In that example the same channel is used for input and output. This -means that if two processes try to retrieve the value at the same -time, the first process may read the response which was triggered by -the second process's request. In simple cases that is fine. For more +means that if two goroutines try to retrieve the value at the same +time, the first goroutine may read the response which was triggered by +the second goroutine's request. In simple cases that is fine. For more complex cases, pass in a channel.
type cmd2 struct { get bool; val int; ch <- chan int; } func manager2(ch chan cmd2) { - var val int = 0; - for { - c := <- ch - if c.get { c.ch <- val } - else { val = c.val } - } + var val int = 0; + for { + c := <- ch + if c.get { c.ch <- val } + else { val = c.val } + } }@@ -601,9 +631,9 @@ To use manager2, given a channel to it:func f4(ch <- chan cmd2) int { - my_ch := make(chan int); - c := cmd2 { true, 0, my_ch }; // Composite literal syntax. - ch <- c; - return <- my_ch; + myCh := make(chan int); + c := cmd2{ true, 0, myCh }; // Composite literal syntax. + ch <- c; + return <- myCh; }