You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
varb = a[lo:hi] // creates a slice (view of the array) from index lo to hi-1
varb = a[1:4] // slice from index 1 to 3
varb = a[:3] // missing low index implies 0
varb = a[3:] // missing high index implies len(a)
// create a slice with make
a = make([]byte, 5, 5) // first arg length, second capacity
a = make([]byte, 5) // capacity is optional
// create a slice from an array
x:= [3]string{"Лайка", "Белка", "Стрелка"}
s:= x[:] // a slice referencing the storage of x
```
### Operations on Arrays and Slices
`len(a)` gives you the length of an array/a slice. It's a built-in function, not a attribute/method on the array.
```go
// loop over an array/a slice
fori, e:=range a {
// i is the index, e the element
}
// if you only need e:
for_, e:=range a {
// e is the element
}
// ...and if you only need the index
fori:=range a {
}
// In Go pre-1.4, you'll get a compiler error if you're not using i and e.
// Go 1.4 introduced a variable-free form, so that you can do this
forrange time.Tick(time.Second) {
// do it once a sec
}
```
## Maps
```go
varmmap[string]int
m = make(map[string]int)
m["key"] = 42
fmt.Println(m["key"])
delete(m, "key")
elem, ok:= m["key"] // test if key "key" is present and retrieve it, if so
// map literal
varm = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
```
## Structs
There are no classes, only structs. Structs can have methods.
```go
// A struct is a type. It's also a collection of fields
// Declaration
typeVertexstruct {
X, Yint
}
// Creating
varv = Vertex{1, 2}
varv = Vertex{X: 1, Y: 2} // Creates a struct by defining values with keys
// Accessing members
v.X = 4
// You can declare methods on structs. The struct you want to declare the
// method on (the receiving type) comes between the the func keyword and
// the method name. The struct is copied on each method call(!)
func(vVertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
// Call method
v.Abs()
// For mutating methods, you need to use a pointer (see below) to the Struct
// as the type. With this, the struct value is not copied for the method call.
func(v *Vertex) add(nfloat64) {
v.X += n
v.Y += n
}
```
**Anonymous structs:**
Cheaper and safer than using `map[string]interface{}`.
```go
point:=struct {
X, Yint
}{1, 2}
```
## Pointers
```go
p:=Vertex{1, 2} // p is a Vertex
q:= &p // q is a pointer to a Vertex
r:= &Vertex{1, 2} // r is also a pointer to a Vertex
// The type of a pointer to a Vertex is *Vertex
vars *Vertex = new(Vertex) // new creates a pointer to a new struct instance
```
## Interfaces
```go
// interface declaration
typeAwesomizerinterface {
Awesomize() string
}
// types do *not* declare to implement interfaces
typeFoostruct {}
// instead, types implicitly satisfy an interface if they implement all required methods
func(fooFoo) Awesomize() string {
return"Awesome!"
}
```
## Embedding
There is no subclassing in Go. Instead, there is interface and struct embedding.
```go
// ReadWriter implementations must satisfy both Reader and Writer
typeReadWriterinterface {
Reader
Writer
}
// Server exposes all the methods that Logger has
typeServerstruct {
Hoststring
Portint
*log.Logger
}
// initialize the embedded type the usual way
server:= &Server{"localhost", 80, log.New(...)}
// methods implemented on the embedded struct are passed through
server.Log(...) // calls server.Logger.Log(...)
// the field name of the embedded type is its type name (in this case Logger)
varlogger *log.Logger = server.Logger
```
## Errors
There is no exception handling. Functions that might produce an error just declare an additional return value of type `Error`. This is the `Error` interface:
```go
typeerrorinterface {
Error() string
}
```
A function that might return an error:
```go
funcdoStuff() (int, error) {
}
funcmain() {
result, error:=doStuff()
if (error != nil) {
// handle error
} else {
// all is good, use result
}
}
```
# Concurrency
## Goroutines
Goroutines are lightweight threads (managed by Go, not OS threads). `go f(a, b)` starts a new goroutine which runs `f` (given `f` is a function).
```go
// just a function (which can be later started as a goroutine)
funcdoStuff(sstring) {
}
funcmain() {
// using a named function in a goroutine
godoStuff("foobar")
// using an anonymous inner function in a goroutine
gofunc (x int) {
// function body goes here
}(42)
}
```
## Channels
```go
ch:=make(chanint) // create a channel of type int
ch <-42// Send a value to the channel ch.
v:=<-ch // Receive a value from ch
// Non-buffered channels block. Read blocks when no value is available, write blocks if a value already has been written but not read.
// Create a buffered channel. Writing to a buffered channels does not block if less than <buffer size> unread values have been written.
ch:=make(chanint, 100)
close(c) // closes the channel (only sender should close)
// read from channel and test if it has been closed
v, ok:=<-ch
// if ok is false, channel has been closed
// Read from channel until it is closed
fori:=range ch {
fmt.Println(i)
}
// select blocks on multiple channel operations, if one unblocks, the corresponding case is executed
funcdoStuff(channelOut, channelInchanint) {
select {
case channelOut <-42:
fmt.Println("We could write to channelOut!")
casex:=<- channelIn:
fmt.Println("We could read from channelIn")
case<-time.After(time.Second * 1):
fmt.Println("timeout")
}
}
```
### Channel Axioms
- A send to a nil channel blocks forever
```go
varcchanstring
c <-"Hello, World!"
// fatal error: all goroutines are asleep - deadlock!
```
- A receive from a nil channel blocks forever
```go
varcchanstring
fmt.Println(<-c)
// fatal error: all goroutines are asleep - deadlock!
```
- A send to a closed channel panics
```go
varc = make(chanstring, 1)
c <-"Hello, World!"
close(c)
c <-"Hello, Panic!"
// panic: send on closed channel
```
- A receive from a closed channel returns the zero value immediately
```go
varc = make(chanint, 2)
c <-1
c <-2
close(c)
fori:=0; i < 3; i++ {
fmt.Printf("%d", <-c)
}
// 1 2 0
```
# Snippets
## HTTP Server
```go
package main
import (
"fmt"
"net/http"
)
// define a type for the response
typeHellostruct{}
// let that type implement the ServeHTTP method (defined in interface http.Handler)
func(hHello) ServeHTTP(whttp.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello!")
}
funcmain() {
varh Hello
http.ListenAndServe("localhost:4000", h)
}
// Here's the method signature of http.ServeHTTP:
// type Handler interface {
// ServeHTTP(w http.ResponseWriter, r *http.Request)