-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgo_for_cpp_programmers.html
626 lines (525 loc) · 31.1 KB
/
go_for_cpp_programmers.html
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
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<!-- Go For C++ Programmers -->
</head><body>
<p><!-- Go is a systems programming language intended to be a
general-purpose
systems language, like C++.
These are some notes on Go for experienced C++ programmers. This
document discusses the differences between Go and C++, and says little
to nothing about the similarities. -->
Go é uma linguagem de programação de sistemas destinada a ser uma
linguagem de propósito geral, como C++. Estas são algumas notas sobre
Go para programadores C++ experientes. Este documento aborda as
diferenças entre o Go e C++, e diz pouco ou nada sobre as semelhanças
entre elas.
</p>
<p><!-- For a more general introduction to Go, see the
<a href="go_tutorial.html">Go tutorial</a> and
<a href="effective_go.html">Effective Go</a>.-->
Para uma introdução mais geral de Go, veja os textos <a href="go_tutorial.html">Go tutorial</a> e <a href="effective_go.html">Effective
Go</a>.
</p>
<p><!-- For a detailed description of the Go language, see the
<a href="go_spec.html">Go spec</a>.-->
Para uma descrição detalhada da linguagem Go, veja o texto <a href="go_spec.html">Go spec</a>.
</p>
<h2 id="Conceptual_Differences">Diferenças Conceituais</h2>
<ul>
<li><!-- Go does not have classes with constructors or destructors.
Instead of class methods, a class inheritance hierarchy, and virtual
functions, Go provides <em>interfaces</em>, which are <a
href="#Interfaces">discussed in more detail below</a>. Interfaces are
also used where C++ uses templates.-->Go não tem classes com
construtores ou destrutores. Em vez de métodos de classe, hierarquia de
herança de classes e funções virtuais, Go fornece <em>interfaces</em>,
que são <a href="#Interfaces">discutidas detalhadamente logo abaixo</a>.
<em>Interfaces</em> também são
usadas onde C++ usa <em>templates</em>.
</li>
<li>Go usa um coletor de lixo. Não é necessário (ou possível) liberar memória
explicitamente. O coletor de lixo é (destinado a ser) incremental e
altamente eficiente em processadores modernos.<br>
</li>
<li>Go utiliza ponteiros mas não utiliza aritmética de ponteiros. Você não pode utilizar uma variável ponteiro para percorrer os <em>bytes</em> de uma <em>string</em>.<br>
</li>
<li><!-- Arrays in Go are first class values. When an array is used as a function parameter, the function receives a copy of the array, not a pointer to it. However, in practice functions often use slices for parameters; slices hold pointers to underlying arrays. Slices are <a href="#Slices">discussed further below</a>. -->Matrizes em Go são valores de primeira classe. Quando uma matriz é usada como um parâmetro de função, a função recebe uma cópia da matriz, e não um ponteiro para ela. Entretanto, na prática, muitas funções utilizam <em>slices</em> para os parâmetros; <em>slices</em> reteem ponteiros para subcamadas das matrizes. <em>Slices</em> são <a href="#Slices">discutidos logo abaixo</a>.
</li>
<li><!-- Strings are provided by the language. They may not be changed
once they have been created. -->As <em>strings</em> são fornecidas pela linguagem. Elas não podem ser modificadas uma vez que foram criadas.</li>
<li><!--Hash tables are provided by the language. They are called maps.-->Tabelas <em>hash</em> são fornecidas pela linguagem. Elas são chamadas de <em>maps</em>.</li>
<li><!--Separate threads of execution, and communication channels between
them, are provided by the language. This is <a href="#Goroutines">discussed
further below</a>.-->A linguagem também fornece <em>threads</em> separados de execução e canais de comunicação entre eles. Isto é <a href="#Goroutines">discutido logo abaixo</a>.</li>
<li><!--Certain types (maps and channels, described further below) are
passed by reference, not by value. That is, passing a map to a function
does not copy the map, and if the function changes the map the change
will be seen by the caller. In C++ terms, one can think of these as
being reference types.-->Certos tipos (<em>maps</em> e canais), descritos logo abaixo, são passados por referência e não por valor. Isto é, um <em>map</em> não é copiado quando é passado para uma função e se uma função muda o <em>map</em> a mudança será percebida pelo chamador da função. Em termos de C++, pode-se considerá-lo como tipo de referência.</li>
<li><!--Go does not use header files. Instead, each source file is part
of a defined <em>package</em>. When a package defines an object (type,
constant, variable, function) with a name starting with an upper case
letter, that object is visible to any other file which imports that
package. -->Go não usa arquivos de cabeçalho. Em vez disso, cada arquivo fonte é parte de um <em>pacote</em> definido. Quando um pacote define um objeto (tipo, constante, variável, função) com um nome iniciando com letra maiúscula, aquele objeto é visível a qualquer outro arquivo que importa o pacote.
</li>
<li><!--Go does not support implicit type conversion. Operations that mix
different types require casts (called conversions in Go).-->Go não suporta conversão implícita de tipo. As operações que misturam diferentes tipos requerem <em>casts</em> (chamados de conversões em GO).</li>
<li><!--Go does not support function overloading and does not support
user defined operators.-->Go não suporta sobrecarga de função e não suporta operadores definidos pelos usuários. </li>
<li><!--Go does not support <code>const</code> or <code>volatile</code>
qualifiers. -->Go não suporta qualificadores <code>const</code> ou <code>volatile</code>.</li>
<li><!--Go uses <code>nil</code> for invalid pointers, where C++ uses <code>NULL</code>
or simply <code>0</code>. -->Go utiliza <code>nil</code> para indicar ponteiros inválidos onde C++ usa <code>NULL</code>.</li>
</ul>
<h2 id="Syntax">Sintaxe</h2>
<p>
<!--The declaration syntax is reversed compared to C++. You write the name
followed by the type. Unlike in C++, the syntax for a type does not
match
the way in which the variable is used. Type declarations may be read
easily from left to right.-->A sintaxe da declaração é invertida em relação ao C++. Você escreve o nome
seguido do tipo. Ao contrário do C++, a sintaxe para um tipo não corresponde a maneira em que a variável é usada. Declarações de tipo podem ser lidas facilmente da esquerda para a direita.
</p>
<pre><b>Go C++</b><br>var v1 int; // int v1;<br>var v2 string; // const std::string v2; (aproximadamente)<br>var v3 [10]int; // int v3[10];<br>var v4 []int; // int* v4; (aproximadamente)<br>var v5 struct { f int }; // struct { int f; } v5;<br>var v6 *int; // int* v6; (mas sem aritmética de ponteiros)<br>var v7 map[string]int; // unordered_map<string, int>* v7; (aproximadamente)<br>var v8 func(a int) int; // int (*v8)(int a);<br></pre>
<p>
<!--Declarations generally take the form of a keyword followed by the name
of the object being declared. The keyword is one of <code>var</code>,
<code>func</code>,
<code>const</code>, or <code>type</code>. Method declarations are a
minor
exception in that
the receiver appears before the name of the object being declared; see
the <a href="#Interfaces">discussion of interfaces</a>.-->
Declarações em geral assumem a forma de palavra-chave, seguido do nome do objeto a ser declarado. A palavra-chave é uma das seguintes <code>var</code>, <code>func</code>, <code>const</code>, ou <code>type</code>. Declarações de métodos são uma pequena exceção em que o receptor aparece antes do nome do objeto a ser declarada; veja <a href="#Interfaces">discussões de interfaces</a>.
</p>
<p><!--You can also use a keyword followed by a series of declarations in
parentheses.--> Você também pode usar uma palavra-chave seguinda de diversas declarações entre parênteses.
</p>
<pre>var (<br> i int;<br> m float<br>)<br></pre>
<p>
<!--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:-->
Quando declarar uma função, você deve fornecer um nome para cada parâmetro ou não fornecer um nome para cada parâmetro, você não pode omitir alguns nomes e fornecer outros. Você pode agrupar vários nomes com o mesmo tipo:
</p>
<pre>func f(i, j, k int, s, t string);<br></pre>
<p>
<!--A variable may be initialized when it is declared. When this is done,
specifying the type is permitted but not required. When the type is
not specified, the type of the variable is the type of the
initialization expression.-->
Uma variável pode ser inicializada quando ela é declarada. Quando isso é feito, especificando o tipo é permitido, mas não obrigatório. Quando o tipo não é especificado, o tipo da variável é o tipo de expressão de inicialização.
</p>
<pre>var v = *p;<br></pre>
<p>
<!--See also the <a href="#Constants">discussion of constants, below</a>.
If a variable is not initialized explicitly, the type must be
specified.
In that case it will be
implicitly initialized to the type's zero value (0, nil, etc.). There
are no
uninitialized variables in Go.-->
Veja também a <a href="#Constants"> discussão sobre constantes abaixo </a>. Se uma variável não é inicializada explicitamente, seu tipo deve ser especificado. Nesse caso, será implicitamente inicializado para o valor do tipo zero (0, nil, etc.). Não há variáveis não-inicializadas em Go.
</p>
<p><!--Within a function, a short declaration syntax is available with-->
Dentro de uma função, uma sintaxe de declaração curta é disponível com
<code>:=</code> .
</p>
<pre>v1 := v2;<br></pre>
<p>
<!--This is equivalent to-->
Isto é equivalente a
</p>
<pre>var v1 = v2;<br></pre>
<p>
<!--Go permits multiple assignments, which are done in parallel.-->
Go permite múltiplas atribuições, que são feitas em paralelo.
</p>
<pre>i, j = j, i; // Troca de valores entre i e j.<br></pre>
<p>
<!--Functions may have multiple return values, indicated by a list in
parentheses. The returned values can be stored by assignment
to a list of variables.-->
Funções podem ter valores de retorno múltiplos, indicados por uma lista entre parênteses. Os valores retornados podem ser armazenados por atribuição a uma lista de variáveis.
</p>
<pre>func f() (i int, j int);<br>v1, v2 = f();<br></pre>
<p>
<!--Go treats semicolons as separators, not terminators. Moreover,
semicolons may be omitted after the closing parenthesis of a
declaration
block or after a closing brace that is not part of an expression
(e.g., <code>var s struct {}</code> or <code>{ x++ }</code>).
Semicolons are never required at the
top level of a file (between global declarations). However, they are
always <em>permitted</em> at
the end of a statement, so you can continue using them as in C++.-->
Go trata as vírgulas como separadores, não terminadores. Além disso, a vírgula pode ser omitida após o fechamento de parêntese de um bloco de declaração ou após um fechamento de chave que não faz parte de uma expressão (por exemplo, <code> var s struct {}</code> ou <code>{x++}</code>). As vírgulas nunca são necessárias na parte superior de um arquivo (entre as declarações globais). No entanto, elas são sempre <em>permitidas</em> no final de uma declaração, então você pode continuar a usá-las como em C++.
</p>
<p><!--When using a pointer to a struct, you use <code>.</code> instead
of <code>-></code>.
Thus syntactically speaking a structure and a pointer to a structure
are used in the same way.-->
Ao usar um ponteiro para uma estrutura, use <code>.</code> em vez de <code>-></code>. Assim, sintaticamente falando, uma estrutura e um ponteiro para uma estrutura são utilizados da mesma forma.
</p>
<pre>type myStruct struct { i int }<br>var v9 myStruct; // v9 é do tipo estrutura<br>var p9 *myStruct; // p9 é um ponteiro para uma estrutura<br>f(v9.i, p9.i)<br></pre>
<p>
<!--Go does not require parentheses around the condition of a <code>if</code>
statement, or the expressions of a <code>for</code> statement, or the
value of a
<code>switch</code> statement. On the other hand, it does require curly
braces
around the body of an <code>if</code> or <code>for</code> statement.-->
Go não requer parênteses em torno da condição de uma instrução <code>if</code>, ou em torno das expressões de uma instrução <code>for</code>, ou em torno do valor de uma instrução <code>switch</code>. Por outro lado, requer chaves
em torno do corpo de uma instrução <code>if</code> ou <code>for</code>.
</p>
<pre>if a < b { f() } // Válido<br>if (a < b) { f() } // Válido (a condição é a expressão entre parênteses)<br>if (a < b) f(); // INVÁLIDO<br>for i = 0; i < 10; i++ {} // Válido<br>for (i = 0; i < 10; i++) {} // INVÁLIDO<br></pre>
<p>
<!--Go does not have a <code>while</code> statement nor does it have a
<code>do/while</code>
statement. The <code>for</code> statement may be used with a single
condition,
which makes it equivalent to a <code>while</code> statement. Omitting
the
condition entirely is an endless loop.-->
Go não tem a instrução <code>while</code> nem tem as declarações <code>do/while</code>. A instrução <code>for</code> pode ser usada com uma única condição, o que o torna equivalente a uma instrução <code>while</code>. Um loop infinito é conseguido omitindo-se a condição inteiramente.
</p>
<p><!--Go permits <code>break</code> and <code>continue</code> to specify
a label.
The label must
refer to a <code>for</code>, <code>switch</code>, or <code>select</code>
statement.-->
Go permite as declarações <code>break</code> e <code>continue</code> na especificação de um <em>label</em>. O <em>label</em> deve-se referir as declarações <code>for</code>, <code>switch</code>, ou <code>select</code>.
</p>
<p><!--In a <code>switch</code> statement, <code>case</code> labels do
not fall
through. You can
make them fall through using the <code>fallthrough</code> keyword.
This applies
even to adjacent cases.-->
Em uma instrução <code>switch</code>, a execução do código para em cada ocorrência da instrução <code>case</code> sem a necessidade de utilizar um <code>break</code>. Você pode conseguir comportamento semelhante a da instrução <code>switch</code> do C++ utilizando a palavra-chave <code>fallthrough</code>. Isso se aplica mesmo aos casos adjacentes.
</p>
<pre>switch i {<br>case 0: // vazio<br>case 1:<br> f() // f não é chamado mesmo que i == 0!<br>}<br></pre>
<p>
<!--But a <code>case</code> can have multiple values.-->
Mas um <code>case</code> pode ter múltiplos valores.
</p>
<pre>switch i {<br>case 0, 1:<br> f() // f é chamado se i == 0 || i == 1.<br>}<br></pre>
<p>
<!--The values in a <code>case</code> 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 <code>switch</code>
value is omitted it defaults to <code>true</code>.-->
Os valores em um <code>case</code> não precisam ser constantes ou mesmo inteiros; qualquer tipo que suporte o operador de comparação, como uma <em>string</em> ou um ponteiro, podem ser usadas e se o valor do <code>switch</code> for omitido ele utilizará o valor padrão <code>true</code>.
</p>
<pre>switch {<br>case i < 0:<br> f1()<br>case i == 0:<br> f2()<br>case i > 0:<br> f3()<br>}<br></pre>
<p>
<!--The <code>++</code> and <code>--</code> operators may only be used in
statements, not in expressions.
You cannot write <code>c = *p++</code>. <code>*p++</code> is parsed
as
<code>(*p)++</code>.-->
Os operadores <code>++</code> e <code>--</code> podem apenas ser usados em declarações, não em expressões. Você não pode escrever <code>c = *p++</code>. <code>*p++</code> é considerado como <code>(*p)++</code>.-->
</p>
<p><!--The <code>defer</code> statement may be used to call a function after the function containing the <code>defer</code> statement returns.-->
A instrução <code>defer</code> pode ser usada para chamar uma função após a função que contém a instrução <code>defer</code> retornar.
</p>
<pre>fd := open("filename");<br>defer close(fd); // fd será fechado quando esta função retornar.<br></pre>
<h2 id="Constants">Constantes</h2>
<!--<p>
In Go constants may be <i>untyped</i>. This applies even to constants
named with a <code>const</code> declaration, if no
type is given in the declaration and the initializer expression uses
only
untyped constants.
A value derived from an untyped constant becomes typed when it
is used within a context that
requires a typed value. This permits constants to be used relatively
freely without requiring general implicit type conversion.-->
As constantes em Go podem ser declaradas <i>sem tipo</i>. Isso se aplica mesmo as constantes nomeadas com a instrução <code>const</code>, se nenhum tipo é dado na declaração e a expressão de inicialização usa apenas constantes sem tipo. Um valor derivado de uma constante sem tipo torna-se tipada quando ela é usada dentro de um contexto que requer um valor tipado. Isso permite constantes serem usadas de forma relativamente livre sem necessidade de conversão de tipo geral implícita.
</p>
<pre>var a uint;<br>f(a + 1) // constante numérica não tipada "1" torna-se tipada por uint<br></pre>
<p>
<!--The language does not impose any limits on the size of an untyped
numeric constant or constant expression. A limit is only applied when
a constant is used where a type is required.-->
A linguagem não impõe qualquer limite no tamanho de uma constante numérica não tipada ou expressão constante. O limite é apenas aplicado quando a constante é usada onde um tipo é requerido.
</p>
<pre>const huge = 1 << 100;<br>f(huge >> 98)<br></pre>
<p>
<!--Go does not support enums. Instead, you can use the special name
<code>iota</code> in a single <code>const</code> declaration to get a
series of increasing
value. When an initialization expression is omitted for a <code>const</code>,
it reuses the preceding expression.-->
Go não suporta enumerações. Em vez disso, você pode usar a instrução especial <code>iota</code> em uma instrução simples <code>const</code> para conseguir uma série de valores crescentes. Quando uma espressão de inicialização é omitida por uma <code>const</code>, ela reutiliza uma expressão anterior.
</p>
<pre>const (<br> red = iota; // red == 0<br> blue; // blue == 1<br> green // green == 2<br>)<br></pre>
<h2 id="Slices">Slices</h2>
<p>
<!--A slice is conceptually a struct with three fields: a
pointer to an array, a length, and a capacity.
Slices support
the <code>[]</code> operator to access elements of the underlying
array.
The builtin
<code>len</code> function returns the
length of the slice. The builtin <code>cap</code> function returns the
capacity.-->
Um <em>slice</em> é conceitualmente uma estrutura com três campos: um ponteiro para um array, um comprimento, e uma capacidade. Os <em>slices</em> suportam o operador <code>[]</code> para acessar os elementos da matriz subjacente. A função pré-definida <code>len</code> retorna o comprimento de um <em>slice</em>. A função pré-definida <code>cap</code> retorna a capacidade.
</p>
<p><!--Given an array, or another slice, a new slice is created via
<code>a[I:J]</code>. This
creates a new slice which refers to <code>a</code>, starts at
index <code>I</code>, and ends before index
<code>J</code>. It has length <code>J - I</code>.
The new slice refers to the same array
to which <code>a</code>
refers. That is, changes made using the new slice may be seen using
<code>a</code>. The
capacity of the new slice is simply the capacity of <code>a</code>
minus
<code>I</code>. The capacity
of an array is the length of the array. You may also assign an array
pointer
to a variable of slice type; given <code>var s []int; var a[10] int</code>,
the assignment <code>s = &a</code> is equivalent to
<code>s = a[0:len(a)]</code>.-->
Dada uma matriz, ou outro <em>slice</em>, um novo <em>slice</em> é criado usando <code>a[I:J]</code>. Este comando cria um novo <em>slice</em> que se refere a <code>a</code>, com índice inicial <code>I</code>, e com índice final antes de <code>J</code>. Seu comprimento é <code>J - I</code>. O novo <em>slice</em> se refere a mesma matriz que <code>a</code> se refere. Isto é, mudanças feitas usando o novo <em>slice</em> pode ser visto usando <code>a</code>. A capacidade de um novo <em>slice</em> é simplesmente a capacidade de <code>a</code> menos <code>I</code>. A capacidade de uma matriz é o comprimento de uma matriz. Você pode também atribuir um ponteiro de matriz para uma variável do tipo <em>slice</em>; dado <code>var s []int; var a[10] int</code>,
a atribuição <code>s = &a</code> é equivalente a <code>s = a[0:len(a)]</code>.
</p>
<p><!--What this means is that Go uses slices for some cases where C++ uses
pointers.
If you create a value of type <code>[100]byte</code> (an array of 100
bytes,
perhaps a
buffer) and you want to pass it to a function without copying it, you
should
declare the function parameter to have type <code>[]byte</code>, and
pass the
address
of the array. Unlike in C++, it is not
necessary to pass the length of the buffer; it is efficiently
accessible via
<code>len</code>.-->
Isso significa que Go usa <em>slices</em> para alguns casos onde C++ usa ponteiros. Se você criar um valor do tipo <code>[100]byte</code> (uma matriz de 100 bytes, talvez um buffer) e você quer passá-la para uma cunção sem copiá-la, você de declarar o parâmetro de função para o tipo <code>[]byte</code>, e passar o endereço para a matriz. Ao contrário de C++, não é necessário passar o comprimento do <em>buffer</em>; isto é eficientemente acessado via instrução <code>len</code>.
</p>
<p><!--The slice syntax may also be used with a string. It returns a new
string,
whose value is a substring of the original string.
Because strings are immutable, string slices can be implemented
without allocating new storage for the slices's contents.-->
A sintaxe do <code>slice</code> pode também ser usada com uma <code>string</code>. Ela retorna uma nova <code>string</code>, cujo valor é uma substring da <code>string</code> original. Por serem as <code>strings</code> imutáveis. Os <code>slices</code> de <em>strings</em> podem ser implementados sem alocar novo espaço de memória para o conteúdo dos <code>slices</code>.
</p>
<h2 id="Making_values">Criando Valores</h2>
<p>
Go has a builtin function <code>new</code> which takes a type and
allocates space
on the heap. The allocated space will be zero-initialized for the type.
For example, <code>new(int)</code> allocates a new int on the heap,
initializes it with the value <code>0</code>,
and returns its address, which has type <code>*int</code>.
Unlike in C++, <code>new</code> is a function, not an operator;
<code>new int</code> is a syntax error.
</p>
<p>Map and channel values must be allocated using the builtin function
<code>make</code>.
A variable declared with map or channel type without an initializer
will be
automatically initialized to <code>nil</code>.
Calling <code>make(map[int]int)</code> returns a newly allocated value
of
type <code>map[int]int</code>.
Note that <code>make</code> returns a value, not a pointer. This is
consistent with
the fact that map and channel values are passed by reference. Calling
<code>make</code> with
a map type takes an optional argument which is the expected capacity of
the
map. Calling <code>make</code> with a channel type takes an optional
argument which sets the
buffering capacity of the channel; the default is 0 (unbuffered).
</p>
<p>The <code>make</code> function may also be used to allocate a
slice.
In this case it
allocates memory for the underlying array and returns a slice referring
to it.
There is one required argument, which is the number of elements in the
slice.
A second, optional, argument is the capacity of the slice. For example,
<code>make([]int, 10, 20)</code>. This is identical to
<code>new([20]int)[0:10]</code>. Since
Go uses garbage collection, the newly allocated array will be discarded
sometime after there are no references to the returned slice.
</p>
<h2 id="Interfaces">Interfaces</h2>
<p>
Where C++ provides classes, subclasses and templates,
Go provides interfaces. A
Go interface is similar to a C++ pure abstract class: a class with no
data members, with methods which are all pure virtual. However, in
Go, any type which provides the methods named in the interface may be
treated as an implementation of the interface. No explicitly declared
inheritance is required. The implementation of the interface is
entirely separate from the interface itself.
</p>
<p>A method looks like an ordinary function definition, except that it
has a <em>receiver</em>. The receiver is similar to
the <code>this</code> pointer in a C++ class method.
</p>
<pre>type myType struct { i int }<br>func (p *myType) get() int { return p.i }<br></pre>
<p>
This declares a method <code>get</code> associated with <code>myType</code>.
The receiver is named <code>p</code> in the body of the function.
</p>
<p>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.
</p>
<p>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.
</p>
<pre>type myInteger int<br>func (p myInteger) get() int { return int(p) } // Conversion required.<br>func f(i int) { }<br>var v myInteger<br>// f(v) is invalid.<br>// f(int(v)) is valid; int(v) has no defined methods.<br></pre>
<p>
Given this interface:
</p>
<pre>type myInterface interface {<br> get() int;<br> set(i int);<br>}<br></pre>
<p>
we can make <code>myType</code> satisfy the interface by adding
</p>
<pre>func (p *myType) set(i int) { p.i = i }<br></pre>
<p>
Now any function which takes <code>myInterface</code> as a parameter
will accept a
variable of type <code>*myType</code>.
</p>
<pre>func getAndSet(x myInterface) {}<br>func f1() {<br> var p myType;<br> getAndSet(&p);<br>}<br></pre>
<p>
In other words, if we view <code>myInterface</code> as a C++ pure
abstract
base
class, defining <code>set</code> and <code>get</code> for
<code>*myType</code> made <code>*myType</code> automatically
inherit from <code>myInterface</code>. A type may satisfy multiple
interfaces.
</p>
<p>An anonymous field may be used to implement something much like a
C++ child
class.
</p>
<pre>type myChildType struct { myType; j int }<br>func (p *myChildType) get() int { p.j++; return p.myType.get() }<br></pre>
<p>
This effectively implements <code>myChildType</code> as a child of
<code>myType</code>.
</p>
<pre>func f2() {<br> var p myChildType;<br> getAndSet(&p)<br>}<br></pre>
<p>
The <code>set</code> method is effectively inherited from
<code>myChildType</code>, because
methods associated with the anonymous field are promoted to become
methods
of the enclosing type. In this case, because <code>myChildType</code>
has an
anonymous field of type <code>myType</code>, the methods of
<code>myType</code> also become methods of <code>myChildType</code>.
In this example, the <code>get</code> method was
overridden, and the <code>set</code> method was inherited.
</p>
<p>This is not precisely the same as a child class in C++.
When a method of an anonymous field is called,
its receiver is the field, not the surrounding struct.
In other words, methods on anonymous fields are not virtual functions.
When you want the equivalent of a virtual function, use an interface.
</p>
<p>A variable which has an interface type may be converted to have a
different interface type using a special construct called a type
assertion.
This is implemented dynamically
at runtime, like C++ <code>dynamic_cast</code>. Unlike
<code>dynamic_cast</code>, there does
not need to be any declared relationship between the two interfaces.
</p>
<pre>type myPrintInterface interface {<br> print();<br>}<br>func f3(x myInterface) {<br> x.(myPrintInterface).print() // type assertion to myPrintInterface<br>}<br></pre>
<p>
The conversion to <code>myPrintInterface</code> is entirely dynamic.
It will
work as long as the underlying type of x (the <em>dynamic type</em>)
defines
a <code>print</code> method.
</p>
<p>Because the conversion is dynamic, it may be used to implement
generic
programming similar to templates in C++. This is done by
manipulating values of the minimal interface.
</p>
<pre>type Any interface { }<br></pre>
<p>
Containers may be written in terms of <code>Any</code>, but the caller
must unbox using a type assertion to recover
values of the contained type. As the typing is dynamic rather
than static, there is no equivalent of the way that a C++ template may
inline the relevant operations. The operations are fully type-checked
at runtime, but all operations will involve a function call.
</p>
<pre>type iterator interface {<br> get() Any;<br> set(v Any);<br> increment();<br> equal(arg *iterator) bool;<br>}<br></pre>
<h2 id="Goroutines">Goroutines</h2>
<p>
Go permits starting a new thread of execution (a <em>goroutine</em>)
using the <code>go</code>
statement. The <code>go</code> statement runs a function in a
different, newly created, goroutine.
All goroutines in a single program share the same address space.
</p>
<p>Internally, goroutines act like coroutines that are multiplexed
among
multiple operating system threads. You do not have to worry
about these details.
</p>
<pre>func server(i int) {<br> for {<br> print(i);<br> sys.sleep(10)<br> }<br>}<br>go server(1);<br>go server(2);<br></pre>
<p>
(Note that the <code>for</code> statement in the <code>server</code>
function is equivalent to a C++ <code>while (true)</code> loop.)
</p>
<p>Goroutines are (intended to be) cheap.
</p>
<p>Function literals (which Go implements as closures)
can be useful with the <code>go</code> statement.
</p>
<pre>var g int;<br>go func(i int) {<br> s := 0<br> for j := 0; j < i; j++ { s += j }<br> g = s;<br>}(1000); // Passes argument 1000 to the function literal.<br></pre>
<h2 id="Channels">Channels</h2>
<p>
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 <code><-</code> as a
binary
operator. To
receive a value on a channel, use <code><-</code> as a unary
operator.
When calling
functions, channels are passed by reference.
</p>
<p>The Go library provides mutexes, but you can also use
a single goroutine with a shared channel.
Here is an example of using a manager function to control access to a
single value.
</p>
<pre>type cmd struct { get bool; val int }<br>func manager(ch chan cmd) {<br> var val int = 0;<br> for {<br> c := <- ch<br> if c.get { c.val = val; ch <- c }<br> else { val = c.val }<br> }<br>}<br></pre>
<p>
In that example the same channel is used for input and output.
This is incorrect if there are multiple goroutines communicating
with the manager at once: a goroutine waiting for a response
from the manager might receive a request from another goroutine
instead.
A solution is to pass in a channel.
</p>
<pre>type cmd2 struct { get bool; val int; ch <- chan int; }<br>func manager2(ch chan cmd2) {<br> var val int = 0;<br> for {<br> c := <- ch<br> if c.get { c.ch <- val }<br> else { val = c.val }<br> }<br>}<br></pre>
<p>
To use <code>manager2</code>, given a channel to it:
</p>
<pre>func f4(ch <- chan cmd2) int {<br> myCh := make(chan int);<br> c := cmd2{ true, 0, myCh }; // Composite literal syntax.<br> ch <- c;<br> return <-myCh;<br>}<br></pre>
</body></html>