Go Language: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Tag: Reverted
(Blanked the page)
Tags: Blanking Manual revert Reverted
Line 1: Line 1:
=External=
* The Go Programming Language Specification https://go.dev/ref/spec
* go.dev Documentation https://go.dev/doc/#learning
* Search packages or symbols https://pkg.go.dev


=Internal=
* [[Go#Subjects|Go]]
* [[Python Language]]
* [[Microservices]]
* [[Go_Language_Modularization|Go Language | Modularization]]
* [[Go Functions|Go Language | Functions]]
* [[Go_Language_Object_Oriented_Programming|Go Language | Object Oriented Programming]]
* [[Go Language Error Handling|Go Language | Error Handling]]
* [[Go Concurrency|Go Language | Concurrency]]
=Overview=
Go Language Specification document defines Go as a general-purpose compiled language designed with systems programming in mind. It is [[#Type|statically and strongly typed]] and garbage-collected and has explicit support for concurrent programming. Programs are constructed from [[Go_Language_Modularization#Packages|packages]], whose properties allow efficient management of [[Go_Language_Modularization#Dependencies|dependencies]]. The existing implementations use a traditional compile/link model to generate executable binaries.
Go declarations can be read "naturally" from left to right, which makes it easy to read.
These are several reasons to use Go:
* It [[#Compilation|compiles fast]], and it runs fast.
* [[Go_Language_Goroutines#Overview|Concurrency]] is a fundamental part of the language and it is efficient.
* The [[Go_Language_Modularization#Standard_Library|standard library]] has almost everything one needs.
* It is a terse language and "feels" dynamically typed, but it compiles  straight into machine code.
* It has [[Go_Language_Memory_Management_and_Garbage_Collection#Overview|garbage collection]].
=Printing=
Use <code>[[Go_Printing_to_Stdout_and_Stderr#println.28.29|println()]]</code>:
<syntaxhighlight lang='go'>
println("something")
</syntaxhighlight>
Also see: {{Internal|Go Printing to Stdout and Stderr|Printing to stdout and stderr in Go}}
=Comments=
C-style comments, dropped by the compiler:
<syntaxhighlight lang='go'>
// This is a comment.
var x int // this is another comment
</syntaxhighlight>
Block comments:
<syntaxhighlight lang='go'>
/*
    This is a
    block comment.
*/
</syntaxhighlight>
Comments should be complete sentences and end with a period.
Every exported package member, and the package itself should have a comment. A comment immediately preceding the <code>package</code> declaration is considered the documentation comment for the package as a whole. Longer package comments may warrant a file of their own. The file is usually called <code>doc.go</code>.
The first sentence of the comment should start with the name being exported and provide a summary of it. Function parameters and other identifiers are mentioned without quotation or markup.
Also see: {{Internal|Go_Style#Comments|Go Style}}
=Whitespace=
Whitespace in Go are carriage returns (u+000D), newlines (u+000A), spaces (u+0020) and tabs (u+0009).
=<span id='Keyword'></span>Keywords=
{{External|https://go.dev/ref/spec#Keywords}}
Keywords, or reserved words, can only be used to mean the thing Go expects them to mean. They cannot be used as [[#Identifier|identifiers]]: [[#Variables|variable names]], function names, or as names of other constructs.
:::{|class="wikitable" style="text-align: left;"
| <span id='import_keyword'></span><font face='menlo' size='-2'>[[Go_Packages#Consuming_Packages|import]]</font> ||  <span id='package_keyword'></span><font face='menlo' size='-2'>[[Go_Packages#Declaring_Packages|package]]</font> || <font face='menlo' size='-2'><span id='range_keyword'></span>[[go_Keyword_range|range]]</font> 
|-
| <font face='menlo' size='-2'><span id='var'></span><span id='var_keyword'></span>[[#Variable|var]]</font> || <font face='menlo' size='-2'><span id='if_keyword'></span>[[#Simple_If|if]]</font> ||  <font face='menlo' size='-2'><span id='else_keyword'></span>[[#If.2Felse|else]]</font>
|-
| <font face='menlo' size='-2'><span id='type_keyword'></span>[[#Type_Declaration|type]]</font> ||  <font face='menlo' size='-2'><span id='struct_keyword'></span>[[Go_Structs#Declaration|struct]]</font> || <font face='menlo' size='-2'><span id='interface_keyword'></span>[[Go_Interfaces#Declaration|interface]]</font>
|-
| <font face='menlo' size='-2'><span id='func_keyword'></span>[[Go_Functions#Function_Syntax|func]]</font> ||  <font face='menlo' size='-2'><span id='return_keyword'></span>[[Go_Functions#return|return]]</font>  || <font face='menlo' size='-2'><span id='defer_keyword'></span>[[Go_Functions#defer|defer]]</font>
|-
| <font face='menlo' size='-2'><span id='go_keyword'></span>[[Go_Language_Goroutines#Overview|go]]</font> || <font face='menlo' size='-2'><span id='chan_keyword'></span>[[Go_Channels#Overview|chan]]</font> ||  <font face='menlo' size='-2'><span id='select_keyword'></span>[[Go_Channels#select|select]]</font>
|-
|}
Also see: {{Internal|Variables,_Parameters,_Arguments#Keyword_.28Reserved_Word.29|Variables, Parameters, Arguments &#124; Keywords}}
=<span id='Identifiers'></span><span id='Identifier'></span><span id='Name'></span>Identifiers (Names)=
Names start with a letter. They can have any number of letters, digits and underscores. They are case sensitive, and their spelling and capitalization must be different of that of the [[#Keyword|keywords]] of the language.
Go style recommends camel-case for identifiers. {{Internal|Go_Style#Naming|Go Naming Style}}
==The Blank Identifier (<tt>_</tt>)==
{{External|https://go.dev/ref/spec#Blank_identifier}}
<code>_</code> is the blank identifier. The blank identifier is used to tell the compiler that we want to ignore one return value of a function, [[Go Language Error Handling#ignoring|including errors]], when we're only interested in others, that we don't need a variable or that we want to [[Go_Keyword_import#The_Blank_Identifier_When_Importing_a_Package|import a package that is not directly used]].
The blank identifier can never be referenced.
==Pre-Declared Identifiers==
{{External|https://go.dev/ref/spec#Predeclared_identifiers}}
Pre-declared identifiers are available by default, without needing to import anything. They are implicitly declared in the [[#Universe_Block|universe block]].
===Pre-Declared Zero Value===
:::{|class="wikitable" style="text-align: left;"
| <font face='menlo' size='-2'>[[Go Nil#Overview| nil]]</font>
|-
|}
===Pre-Declared Constants===
:::{|class="wikitable" style="text-align: left;"
| <font face='menlo' size='-2'>[[Go Booleans#Boolean_Literals|true]]</font> || <font face='menlo' size='-2'>[[Go Booleans#Boolean_Literals|false]]</font> ||  <font face='menlo' size='-2'>[[Go iota|iota]]</font>
|-
|}
===Pre-Declared Types===
:::{|class="wikitable" style="text-align: left;"
| <font face='menlo' size='-2'>[[Go Booleans#Overview|bool]]</font> || <font face='menlo' size='-2'>[[Go Strings#Overview|string]]</font> ||  <font face='menlo' size='-2'>[[Go Integers#Overview|uintptr]]</font>  || <font face='menlo' size='-2'>[[Go_Language_Error_Handling#error|error]]</font> ||
|-
| <font face='menlo' size='-2'> [[Go Integers#Overview|int]]</font> || <font face='menlo' size='-2'> [[Go Integers#Overview|int8]]</font> || <font face='menlo' size='-2'> [[Go Integers#Overview|int16]]</font> || <font face='menlo' size='-2'> [[Go Integers#Overview|int32]]</font> || <font face='menlo' size='-2'> [[Go Integers#Overview|int64]]</font>
|-
| <font face='menlo' size='-2'> [[Go Integers#Overview|uint]]</font> || <font face='menlo' size='-2'> [[Go Integers#Overview|uint8]]</font> (<font face='menlo' size='-2'>[[Go Integers#Overview|byte]]</font>) || <font face='menlo' size='-2'> [[Go Integers#Overview|uint16]]</font> || <font face='menlo' size='-2'> [[Go Integers#Overview|uint32]]</font> (<font face='menlo' size='-2'>[[Go Integers#Overview|rune]]</font>) || <font face='menlo' size='-2'> [[Go Integers#Overview|uint64]]</font>
|-
| <font face='menlo' size='-2'> [[Go_Floating_Point#Overview|float32]]</font> || <font face='menlo' size='-2'> [[Go_Floating_Point#Overview|float64]]</font> || <font face='menlo' size='-2'> [[Go_Floating_Point#Overview|complex64]]</font> || <font face='menlo' size='-2'> [[Go_Floating_Point#Overview|complex128]]</font> ||
|-
|}
<font color=darkkhaki>The source code of these types is available in <code>$GO_HOME/src/builtin/builtin.go</code>.</font>
===Pre-Declared Functions===
:::{|class="wikitable" style="text-align: left;"
| <font face='menlo' size='-2'>append()</font> || <font face='menlo' size='-2'>[[Go_Functions#cap.28.29|cap()]]</font> ||  <font face='menlo' size='-2'>close()</font>  || <font face='menlo' size='-2'>complex()</font> || <font face='menlo' size='-2'>copy()</font>
|-
| <font face='menlo' size='-2'>delete()</font> || <font face='menlo' size='-2'> imag()</font> || <font face='menlo' size='-2'> [[Go_Functions#len.28.29|len()]]</font> || <font face='menlo' size='-2'> [[Go_Functions#make.28.29|make()]]</font> || <font face='menlo' size='-2'>new()</font>
|-
|<font face='menlo' size='-2'>panic()</font> || <font face='menlo' size='-2'> [[Go_Printing_to_Stdout_and_Stderr#print.28.29|print()]]</font> || <font face='menlo' size='-2'>[[Go_Printing_to_Stdout_and_Stderr#println.28.29|println()]]</font> || <font face='menlo' size='-2'>real()</font> || <font face='menlo' size='-2'>recover()</font>
|-
|}
<font color=darkkhaki>TODO: when the similar table from [[Go_Functions#Built-in_Functions]] is fully updated, copy it here for convenience.</font>
Also see: {{Internal|Go_Functions#Built-in_Functions|Built-in Functions}}
==<span id='Exported'></span>Exported Identifiers==
{{External|https://go.dev/ref/spec#Exported_identifiers}}
An identifier must be exported to permit access to it from another package. An identifiers is exported if the first character of the identifier's name is a Unicode uppercase letter '''AND''' the identifier is declared in the [[#Package_Block|package block]] or it is a [[Go_Structs#Exported_Fields|field name]] or a [[Go_Language_Object_Oriented_Programming#Methods|method name]]. For more details about package encapsulation see: {{Internal|Go_Packages#Packages_as_Encapsulation_Mechanism|Packages as Encapsulation Mechanism}}
=<span id='Block'></span>Blocks=
{{External|https://go.dev/ref/spec#Blocks}}
A block is a contiguous sequence of declarations and statements. They are also known as '''lexical blocks'''. They can be enclosed in matching curly brackets, in which case they are called [[#Explicit_Block|explicit blocks]], or not, and in that case they're called [[#Implicit_Block|implicit blocks]].
Blocks are hierarchical: blocks can be enclosed in other, larger blocks, recursively.
Blocks are involved when the [[#Scope|scope of a variable]] is determined. Each block can have its own variables, and the visibility rules for a specific variable are defined in relation to blocks.
==Explicit Block==
An explicit block is a sequence of statements enclosed within curly brackets.
<syntaxhighlight lang='go'>
{
  // block
  ...
}
</syntaxhighlight>
A [[Go Functions|function]]'s body is defined as an explicit block.
==Implicit Block==
There are blocks implicitly defined without curly brackets. From the "largest" to "smaller" implicit blocks, there are the [[#Universe_Block|Universe block]], [[#Package_Block|Package blocks]], [[#File_Block|File blocks]] and others.
===Universe Block===
All Go code in existence.
===Package Block===
Each [[Go_Packages#Overview|package]] has a package block, which contains all the code in the package. All identifiers from the package block whose names start with an uppercase letter are [[#Exported_Identifiers|exported]]. It has been suggested that the package global state, which includes all package-level variables, should be kept to a minimum, and avoided altogether if possible. See [[Go_Packages#Package_Global_State|Package Global State]] for more details.
===File Block===
All Go source code in a single file.
====Source File Name Conventions====
* File names are all lowercase and words are separated by underscores (ex. "resource_manager.go")
* File names that begin with "." or "_" are ignored by the go tool.
* Files with the suffix _test.go are only compiled and run by the go test tool.
* Files with os and architecture specific suffixes automatically follow those same constraints, e.g. <code>name_linux.go</code> will only build on linux, <code>name_amd64.go</code> will only build on amd64. This is the same as having a <code>//+build amd64</code> line at the top of the file.
===<tt>if</tt>, <tt>for</tt>, <tt>switch</tt> Blocks===
===<tt>switch</tt> and <tt>select</tt> Clauses Blocks===
=<span id='Variable'><span>Variables=
Variables are names associated with memory locations that store values. Variable name rules are described in the [[#Identifiers|Identifiers]] section. Each variable has a [[#Type|type]]. Because Go is a [[Programming_Languages_Concepts#Static_Typing_vs_Dynamic_Typing|statically typed language]], the type associate with a variable may not change after declaration.
Each variable defined in Go occupies a unique memory location. It is not possible to have two variables that share the same storage location. It is possible to have two variable that point to the same storage location, in case of [[Pointers_in_Go#Overview|pointer variables]], but this is not the same thing as sharing the same storage location. In other words, Go has [[#Reference_Variables|no reference variables]].
==<span id='Reference_Variables'></span><span id='Reference_Variable'></span>(No) Reference Variables==
Go does not have [[Variables,_Parameters,_Arguments#Reference|reference variables]]. Each variable defined in Go occupies a unique memory location, which contains the value of the variable. [[Go_Maps#Overview|Maps]], [[Go_Channels#Overview|channels]], etc. variables are all values, not references. As such, there is no pass-by-referece in Go, everything is passed by value. To achieve behavior similar to pass-by-reference, use pointers. This is explained here: {{Internal|Go_Functions#Pass-by-value_vs._pass-by-pointer_vs._pass-by-reference|Pass by Value vs. Pass by Reference vs. Pass by Pointer in Go}}
==Variable Declaration==
The name and the type of the variable are specified in the variable declaration, which is a statement prefixed by the keyword <code>[[#var|var]]</code>. This style is some times referred to as "long declaration":
<syntaxhighlight lang='go'>
var <variable-name>[, <variable-name-2>, ...]  <type>
</syntaxhighlight>
<syntaxhighlight lang='go'>
var size int
</syntaxhighlight>
<syntaxhighlight lang='go'>
var size, weight int
</syntaxhighlight>
Such a variable declaration is also an '''implicit initialization with the [[Go_Language#Zero_Value|zero value]] of the variable's type'''. Unless you intent to initialize the variable to a non-zero value with the [[#Short_Variable_Declaration|short variable declaration]] <code>:=</code> operator can be used, <code>var var_name var_type</code> is the preferred syntax.
More variables can be declared at the same time with:
<syntaxhighlight lang='go'>
var (
  a int
  b string
  ...
)
</syntaxhighlight>
Also see: {{Internal|Variables,_Parameters,_Arguments#Variable|Variables, Parameters, Arguments}}
<font color=darkkhaki>
What is <code>any</code> in a variable declaration?
<syntaxhighlight lang='go'>
var r any
</syntaxhighlight>
</font>
==Variable Names==
For rules and conventions to use when naming variables, see [[#Identifiers_.28Names.29|Identifiers (Names)]] above. For special rules concerning pointer variable names, see: {{Internal|Pointers_in_Go#Pointer_Variable_Name|Pointers in Go &#124; Pointer Variable Names}}
==Variable Initialization after Declaration==
<syntaxhighlight lang='go'>
var color string
color = "blue"
</syntaxhighlight>
==Variable Initialization in Declaration==
Variables can be initialized in the declaration:
<syntaxhighlight lang='go'>
var color string = "blue"
</syntaxhighlight>
This is redundant, and some editors will render the type name in gray and pop up a soft static analysis warning: "Type can be omitted", because an alternative syntax, [[#Variable_Initialization_with_Type_Inference|initialization with type inference]] is available.
==Variable Initialization with Type Inference==
<syntaxhighlight lang='go'>
var color = "blue"
</syntaxhighlight>
==Idiomatic Variable Naming Conventions==
Variable names should be short rather than long. The closer to declaration a name is used, the shorter it should be. In other words, the farther away from the declaration you use it, the longer the name should be. <code>i</code> is fine when iterating over an array. Two letter variable names should be used for slices or maps.
<syntaxhighlight lang='go'>
var tt []*Thing // tt is many
</syntaxhighlight>
Since references include package names, variable names should not be prefixed with the package name. If the package name is <code>xml</code>, use the name <code>Reader</code>, not <code>XMLReader</code>. In the second case, the full name would be <code>xml.XMLReader</code>.
Also see: {{Internal|Go_Style#Naming|Go Style}}
==Swap Variable Values==
<syntaxhighlight lang='go'>
a, b = b, a
</syntaxhighlight>
Also works with arrays and slices.
==Short Variable Declaration==
The declaration and initialization can be performed together with the <code>:=</code> operator. This obviates the need for the <code>[[#var|var]]</code> keyword and it deploys type inference. This kind of declaration can only be performed inside a [[Go Functions#Short_Variable_Declaration|function]].
<syntaxhighlight lang='go'>
color := "blue"
</syntaxhighlight>
<span id='Multi-Value_Short_Variable_Declaration'></span>The short variable declaration can be used to initialize more than one variable at the same time, when the assignment contains multiple values, or when on the right side of the assignment there is a [[Go_Functions#Multi-Value_Return|function that returns multiple values]]:
<syntaxhighlight lang='go'>
i, j := 0, 1
color, size := someFuncWithTwoReturnValues(...)
</syntaxhighlight>
==Variable Declaration with <tt>new()</tt>==
<code>new()</code> creates a variable or a certain type, specified as the argument of the <code>new()</code> function invocation, and returns a [[#Pointer|pointer]] pointer to that variable.
<syntaxhighlight lang='go'>
ptri := new(int)
*ptri = 3
</syntaxhighlight>
<font color=darkkhaki>Why do we need to involve variables here? There's no variable, new() just allocates space for an instance of a certain type and returns a pointer to it.</font>
==Creating instances with <tt>New()</tt>==
{{Internal|Go New()|Go <tt>New()</tt>}}
==Scope==
The scope of a variable is defined as places in the code where the variable can be accessed. In Go, the scope of a variable can be formally defined by using the concept of [[#Block|block]]: Go is a lexically scoped language using blocks.
Given two blocks b<sub>i</sub> and b<sub>j</sub>, we say that b<sub>i</sub> ≥ b<sub>j</sub> if b<sub>j</sub> is inside (is enclosed in) b<sub>i</sub>. This relationship is transitive.
The formal definition of visibility (or accessibility) of a variable <code>v</code> is: a variable <code>v</code> is visible in a block b<sub>j</sub> if it is declared in a block b<sub>i</sub> so b<sub>i</sub> ≥ b<sub>j</sub>.
If a variable with the same name is declared in two blocks between which there is a an inclusion relationship, the variable defined in the "closest" block takes precedence.
Also see: {{Internal|Go_Functions#Environment_of_a_Function|Environment of a Function}}
==Variable Deallocation==
{{Internal|Go_Language_Memory_Management_and_Garbage_Collection#Variable_Deallocation|Memory Management and Garbage Collection &#124; Variable Deallocation}}
=<span id='Constant'></span>Constants=
{{External|https://go.dev/ref/spec#Constants}}
A constant is a typed expression whose value is known at compile time, and cannot be changed once declared. The compiler detects modification attempts and throws a compilation error. The type is inferred from the right-hand side of the assignment. Multiple constants can be assigned at the same time using enclosing parentheses.
<syntaxhighlight lang='go'>
const <constant_identifier> [constant_type] = <initial_value_literal>
</syntaxhighlight>
<syntaxhighlight lang='go'>
const a = 1
const (
b = 1.1
c = "something"
)
</syntaxhighlight>
==Constant Naming Conventions==
Other languages name their constants with upper caps. In Go, an unexported constant is "maxLength", not "MaxLength" or "MAX_LENGTH".
==Enumerations==
Go does not have formal enums, but the language allows for sets of related, yet distinct constants.
{{Internal|Go Enumerations#Overview|Go Enumerations}}
=<span id='The_Type_System'></span>Type=
{{External|https://go.dev/ref/spec#Types}}
A Go type is similar to types from other languages, in that it defines the range of values and the operations that can be performed with all those values. For more details, see: {{Internal|Programming_Languages_Concepts#Type|Programming Languages Concepts &#124; Types}}
Go is a [[Programming_Languages_Concepts#Strong_Typing|strongly]] and [[Programming_Languages_Concepts#Static_Typing|statically]] typed language with no implicit conversions. This gives Go a stronger type safety than Java, which as implicit conversions, but the code reads more like Python, which has untyped variables.
<font color=darkkhaki>To deplete [[Go Concepts - The Type System]]</font>
==The Primitive vs. Non-Primitive Nature of Types==
A type is said to have a '''primitive nature''' if adding something to, or removing something from a value of that type creates a new value. When passing values of these types to functions, copies the arguments are made inside the function. [[#Integer|Integers]], [[#Floating_Point|floats]], [[#Boolean|booleans]] and [[#String|strings]] are primitive types. Primitive types are some times referred to as '''data types'''. <font color=darkkhaki>The [[#Pointer|pointers]] themselves, but not, in general, the instances the pointers point to, are also a primitive type. The Go language specification says that pointers are a [[#Composite_Types|composite type]].</font>
For '''non-primitive types''', adding or changing something to the value of the type does not create a new value, it instead mutates the existing value. The value itself is changed, while various references in existence point to the mutated value. When such a value is passed to a function, no copy of the value is made, a reference to it is passed instead. When a factory function returns a pointer, it's a good indication that the nature of the value being returned is non-primitive.
Structs can represent data values that could have either a primitive or a non-primitive value. For a discussion on this subject, see [[#Struct|Structs]] below.
More details: Go in Action Section 5.3 "The Nature of Types".
Also see: {{Internal|Programming_Languages_Concepts#The_Primitive_vs._Non-Primitive_Nature_of_Types|Programming Languages Concepts &#124; The Primitive vs. Non-Primitive Nature of Types}}
==Type Declaration==
Types are declared using the keyword <code>type</code>. The <code>type</code> keyword is also used for declaring [[Go_Structs#Declaration|structs]] and [[Go_Interfaces#Declaration|interfaces]].
===Type Alias===
Go allows defining a type alias, or alternate name, for a type. A type declaration is a statement that begins with the keyword <code>[[#type_keyword|type]]</code>:
<syntaxhighlight lang='go'>
type Size int
</syntaxhighlight>
Two different aliases of the same type count as two different types.
==<span id='Data_Types'></span>Primitive (Data) Types==
===<span id='Pointer'></span><span id='The_Referencing_Operator_.26'></span><span id='Dereferencing_Operator'></span><span id='The_Dereferencing_Operator_.2A'></span>Pointers===
{{Internal|Pointers in Go#Overview|Pointers in Go}}
===<span id='String'></span><span id='string'></span><span id='Strings'></span><span id='String_.28string.29'></span>String===
{{Internal|Go Strings|Go Strings}}
===Numbers===
{{External|https://go.dev/ref/spec#Numeric_types}}
====<span id='Integers'></span><span id='int'></span><span id='Integer_.28int.29'></span>Integer====
{{Internal|Go Integers|Go Integers}}
====<span id='Floating_Point'></span><span id='float64'></span><span id='Floating_Point_.28float64.29'></span>Floating Point====
{{Internal|Go Floating Point|Go Floating Point}}
===<span id='Boolean'></span>Booleans===
{{External|https://go.dev/ref/spec#Boolean_types}}
===<span id='Array'></span>Arrays===
In Go, arrays have characteristics of a primitive data type, they are handled as values, and they are passed to function by value. Arrays are at the same time [[Go_Language#Composite_Types|composite types]]. For more details, see: {{Internal|Go_Arrays#Arrays_are_Values|Go Arrays &#124; Arrays are Values}}
==Composite Types==
Go composite types aggregate other data types. In Go, the composite data types are [[#Array|arrays]], [[#Slice|slices]], [[#Map|maps]], [[#Struct|structs]], [[#Pointer|pointers]], [[#Function|functions]], [[#Interface|interfaces]] and [[#Channel|channels]].
===<span id='Array'></span>Arrays===
{{Internal|Go Arrays|Go Arrays}}
===<span id='Slice'></span>Slices===
{{Internal|Go Slices|Go Slices}}
===<span id='Map'></span>Maps===
{{Internal|Go Maps#Overview|Go Maps}}
===<span id='Function'></span>Functions===
{{Internal|Go Functions|Functions}}
===<span id='Channel'></span>Channels===
{{Internal|Go_Channels#Overview|Channels}}
===<tt>type</tt>-Introduced Types===
====<span id='Struct'></span>Structs====
{{Internal|Go Structs#Overview|Structs}}
====<span id='Interface'></span>Interfaces====
{{Internal|Go Interfaces#Override|Interfaces}}
==Reference Type==
<font color=darkkhaki>TODO: [[Go_Concepts_-_The_Type_System#Reference_Types]]</font>
==Type Conversion==
[[Go_Functions#Built-in_Functions|Built-in functions]] are available to do type conversions. The general syntax is:
<syntaxhighlight lang='js'>
newTypeVar = <type-name>(oldTypeVar)
</syntaxhighlight>
<syntaxhighlight lang='go'>
var x int32 = 1
var y int16 = 2
// println(x + y) // compilation will fail on this, cannot apply + on two different types
z := int32(y)
println(x + z)
</syntaxhighlight>
==Zero Value==
0 for <code>int</code>, the empty string "" for string.
One of the elements of Go philosophy is to make the zero value useful. A "zero value" structure should be ready to use and useful. Examples are the byte buffer or <code>[[Go Mutex and RWMutex|sync.Mutex]]</code> where you can just put one of these types inside of your structure, not even allocate it or declare a variable of that type, and just use it. You don't have to call an init function, or think about it. This is even more valuable when you build complex data structures that have these things inside them, because if you build the structure so zero value is meaningful, byte buffer or <code>[[Go Mutex and RWMutex|sync.Mutex]]</code> does not break that.
==Pass by Value vs. Pass by Reference vs. Pass by Pointer in Go==
{{Internal|Go_Functions#Pass_by_Value_vs._Pass_by_Reference_vs._Pass_by_Pointer|Go Functions &#124; Pass by Value vs. Pass by Reference vs. Pass by Pointer}}
==Concrete vs. Interface Types==
<span id='Concrete_Type'></span>A '''concrete type''' is a regular type that is fully specified: it specifies the exact representation of its data, and for every method that declares it as its receiver type, there is implementation. On the other hand, an '''interface type''' is the type resulted from [[Go_Interfaces#Interface_Type|declaring an interface]]. The interface type does not have data, nor method implementations.
An interface type [[Go_Interfaces#Interface_Values|gets mapped]] to a concrete type.
==Type Assertions==
{{Internal|Go Type Assertions#Overview|Type Assertions}}
=Expressions=
[[#Operators|operators]] combine operands into expressions.
==Operators==
{|class="wikitable" style="text-align: left;"
| <span id='Star_Operator'></span><tt>*</tt> || Multiplication, Pointer Dereference  || <code>*</code> has several meanings in Go:<br>&nbsp;&nbsp;- Multiplication operator.<br>&nbsp;&nbsp;- Dereferencing operator. For more details see [[#Dereferencing_Operator|Dereferencing Operator]].<br>&nbsp;&nbsp;- <code>*</code> also designates [[#Pointer|pointer types]] and [[Go_Arrays#Pointer_Array|pointer array types]].
|-
| <span id='Indexing_Operator'></span><tt>[]</tt> || Indexing operator ||Used with [[Go_Strings#Indexing_Operator_.5B.5D|strings]], [[Go_Arrays#Indexing_Operator_.5B.5D|arrays]], [[Go_Slices#Indexing_Operator_.5B.5D|slices]] and [[Go_Maps#Indexing_Operator_.5B.5D|maps]].
|-
| <span id='Arrow_Operator'></span><tt><-</tt> || Arrow operator|| Used to [[Go_Channels#Sending_on_Channels|send]] and [[Go_Channels#Receiving_from_Channels|receive]] data to/from a channel.
|-
|}
===Operator Precedence===
The operators with the highest precedence appear at the top:
{|class="wikitable" style="text-align: left;"
! Category
! Operator
! Associativity
|-
| Postfix ||<center><font face='menlo' size='-2'>()</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>[]</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>-></font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>.</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>++</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>--</font>&nbsp;&nbsp;&nbsp;  </center>|| Left to Right
|-
| Unary || <center><font face='menlo' size='-2'>+</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>-</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>!</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>~</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>++</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>--</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>(type)</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>*</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>&</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>sizeof</font>&nbsp;&nbsp;&nbsp;</center>|| Right to left
|-
| Multiplicative || <center><font face='menlo' size='-2'>*</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>/</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>%</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Additive || <center><font face='menlo' size='-2'>+</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>-</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Shift || <center><font face='menlo' size='-2'><<</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>>></font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Relational  || <center><font face='menlo' size='-2'><</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'><=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>></font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>>=</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Equality  || <center><font face='menlo' size='-2'>==</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>!=</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Bitwise AND  || <center><font face='menlo' size='-2'>&</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Bitwise XOR  || <center><font face='menlo' size='-2'>^</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Bitwise OR  ||<center> <font face='menlo' size='-2'>&#124;</font>&nbsp;&nbsp;&nbsp;</center>|| Left to right
|-
| Logical AND || <center><font face='menlo' size='-2'>&&</font>&nbsp;&nbsp;&nbsp; </center>|| Left to right
|-
| Logical OR  || <center><font face='menlo' size='-2'>&#124;&#124;</font>&nbsp;&nbsp;&nbsp; </center>|| Left to right
|-
| Assignment  || <center><font face='menlo' size='-2'>=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>+=</font>&nbsp;&nbsp;&nbsp; <font face='menlo' size='-2'>-=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>*=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>/=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>%=</font>&nbsp;&nbsp;&nbsp; <font face='menlo' size='-2'>>>=</font>&nbsp;&nbsp;&nbsp; <font face='menlo' size='-2'><<=</font>&nbsp;&nbsp;&nbsp; <font face='menlo' size='-2'>&=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>^=</font>&nbsp;&nbsp;&nbsp;<font face='menlo' size='-2'>&#124;=</font>&nbsp;&nbsp;&nbsp;</center> || Right to Left
|-
| Comma  ||<center><font face='menlo' size='-2'>,</font>&nbsp;&nbsp;&nbsp; </center>|| Left to right
|-
|}
=Control Flow=
Control flow defines the order in which statements are executed in a program. The control flow can be changed by using control structures.
==If Statement==
The <code>if</code> statement specifies the conditional execution of two branches according to the value of a boolean expression. Optionally, the boolean expression [[#Statement_Precedes_Expression |may be preceded by another statement]], which is executed before the expression is evaluated.
===Simple If===
{{External|https://go.dev/ref/spec#If_statements}}
<syntaxhighlight lang='go'>
if <condition> {
  <statements>
}
</syntaxhighlight>
<syntaxhighlight lang='go'>
if x > 5 {
  println(x)
}
</syntaxhighlight>
===If/else===
<syntaxhighlight lang='go'>
if <condition> {
  <statements>
} else {
  <statements>
}
</syntaxhighlight>
<syntaxhighlight lang='go'>
if x > 5 {
  println(x)
} else {
  println("something else")
}
</syntaxhighlight>
<span id='Statement_Precedes_Expression'></span>A special <code>if</code> syntax supports the Go [[Go_Language_Error_Handling#If_Syntax_for_Handling_Errors|error handling idiom that relies on functions returning errors as result value]]:
<syntaxhighlight lang='go'>
var result ...
var err error
if result, err = someFunc(); err != nil {
  // handle error
  return
}
// handle success
...
</syntaxhighlight>
'''Avoid <code>else</code>''' in the idiom above. Do NOT write this:
<syntaxhighlight lang='go'>
if result, err := someFunc(); err {
  // handle error
  ...
} else { // BAD, avoid the "else"
  // handle success
  ... 
}
</syntaxhighlight>
===If/else if/else===
<syntaxhighlight lang='go'>
if <condition> {
  <statements>
} else if <condition> {
  <statements>
} else {
  <statements>
}
</syntaxhighlight>
<syntaxhighlight lang='go'>
if x < 5 {
  println(x)
} else if x == 5 {
  println("is 5")
} else {
  println("something else")
}
</syntaxhighlight>
==For Loops==
The most generic syntax of the <code>for</code> statement is:
<syntaxhighlight lang='go'>
for <init>; <condition>; <update> {
  <statements>
}
</syntaxhighlight>
The <code>for</code> loop executes the <code>init</code> statement and then iterates while the <code>condition</code> evaluates to true. The <code>condition</code> is an expression evaluated on each iteration. <code>condition</code> must evaluate to a boolean. If the expression evaluates to true, the block is executed. At the end of each block execution, the <code>update</code> statement is executed.
The <code>init</code> statement is usually a variable declaration and initialization. Multiple variables can be declared at the same time (for more details, see [[#Short_Variable_Declaration|Short Variable Declaration]] section above):
<syntaxhighlight lang='go'>
for i, j := 0, 0; ... {
  ...
}
</syntaxhighlight>
Examples:
<syntaxhighlight lang='go'>
for i := 0; i < 3; i ++ {
  println(i)
}
</syntaxhighlight>
All three expressions (initialization, condition and update) are optional:
<syntaxhighlight lang='go'>
i := 0
for i < 3 {
  println(i)
  i ++
}
</syntaxhighlight>
<syntaxhighlight lang='go'>
i := 0
for  {
  if i == 3 {
    break
  }
  println(i)
  i ++
}
</syntaxhighlight>
To iterate over an iterable structure, use <code>range</code>:
<syntaxhighlight lang='go'>
ss := []string{"a", "b", "c"}
for index, value := range ss {
  ...
}
</syntaxhighlight>
If the values of the iterable structure are not important, and only the number of elements matters, this syntax can also be used:
<syntaxhighlight lang='go'>
ss := []string{"a", "b", "c"}
for range ss {
  ...
}
</syntaxhighlight>
<code>for</code> can be used to [[Go_Channels#Iterative_Read_from_a_Channel_(Ranging_over_a_Channel)|iterate over values received from a channel]].
==Break==
<code>break</code> exits the closest enclosing loop.
==Continue==
<code>continue</code> skips the rest of the current iteration.
==Switch==
===Tagless Switch===
=Error Handling=
{{Internal|Go Language Error Handling|Error Handling}}
=Modularization=
In Go, programs are constructed from [[Go_Language_Modularization#Packages|packages]]. More details: {{Internal|Go Language Modularization|Go Modularization}}
=Object Oriented Programming=
{{Internal|Go_Language_Object_Oriented_Programming|Object Oriented Programming}}
=Concurrency=
{{Internal|Go_Concurrency#Overview|Go Concurrency}}
=Memory Management and Garbage Collection=
{{Internal|Go_Language_Memory_Management_and_Garbage_Collection|Memory Management and Garbage Collection}}
=Extension=
What is an extension?
=Assertions=
Go does not have assertions. This is why: https://golang.org/doc/faq#assertions
A crude equivalent would be:
<syntaxhighlight lang='go'>
if condition {
  panic(...)
}
</syntaxhighlight>
=Compilation=
Go compiler is fast, for the following reasons:
# All imports must be explicitly listed at the beginning of each source file, so the compiler does not have to read and process the entire file to determine its dependencies.
# The dependencies of a package for a directed acyclic graph - this is enforced - and because there are no cycles, the packages can be compiled separately following a topological sort, possibly in parallel.
# The [[#Object_File|object file]] for a compiled Go package records export information not for just the package itself, but for all its dependencies. When compiling a package, the compiler must read one object file for each import, but need not look beyond these files.
==Cross-Compilation==
{{Internal|Go Cross-Compilation Mac to Linux|Cross-Compilation Mac to Linux}}
==Build Tags==
Special comments called build tags give more control over compilation
<syntaxhighlight lang='go'>
// +build linux darwin
</syntaxhighlight>
For more details on build constraints, see:
<syntaxhighlight lang='bash'>
go doc go/build
</syntaxhighlight>
==<span id='Object_Files'></span>Object File==
The result of the compilation of all source files that constitute a package is stored in an object file. Each package has one object file. Object files have an <code>.a</code> extension. Package object files can be created and locally installed with <code>[[go install#Overview|go install]]</code>. If the linker detects a <code>main</code> package, all interdependent object file are linked to produce the executable.
==Incremental Builds==
An incremental build is a Go compiler feature that allows it to build only the packages that have been changed or are affected by changes, instead of recompiling the entire project code base every time the project is compiled. This behavior is implemented by computing source file hashes and associating them with timestamps. The hashes and the object files produced by builds are stored in a [[Go Build Cache|build cache]].
==Build Cache==
{{Internal|Go Build Cache|Go Build Cache}}
==Executable==
{{Internal|Go_Packages#Executables_and_the_.22main.22_Package|Executables and the "main" Package}}
=Environment Variables=
{{Internal|Go Environment Variables|Go Environment Variables}}
=Annotations=
Go does not have support for annotations. Somewhat similar, but with a much more limited scope are the [[Go_Structs#Tags|struct tags]].
=Go Code Generation=
{{External|https://go.dev/blog/generate}}
=Identity, Equality, Comparability=
The Go notion of '''comparability''' implies that the equality operators <code>==</code> and <code>!=</code> must return the correct values when used.
=Code Examples=
{{Internal|Go Code Examples|Go Code Examples}}

Revision as of 01:09, 15 March 2024