Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
wiki2:go_basics [2017/12/17 18:51] alfred [Goroutines] |
wiki2:go_basics [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 32: | Línea 32: | ||
| ''godoc fmt'' \\ | ''godoc fmt'' \\ | ||
| + | ''godoc fmt Println'' \\ | ||
| If you want to get documentation for the fmt package, type the following command in | If you want to get documentation for the fmt package, type the following command in | ||
| the terminal. The godoc tool also provides browsable documentation on a web interface. To access the documentation through a web-based interface, start the web server provided by the godoc tool. Type the following command in the terminal: \\ | the terminal. The godoc tool also provides browsable documentation on a web interface. To access the documentation through a web-based interface, start the web server provided by the godoc tool. Type the following command in the terminal: \\ | ||
| Línea 76: | Línea 77: | ||
| f := "short" | f := "short" | ||
| </code> | </code> | ||
| + | Go also has another shorthand when you need to define multiple variables: | ||
| + | <code> | ||
| + | var ( | ||
| + | a = 5 | ||
| + | b = 10 | ||
| + | c = 15 | ||
| + | ) | ||
| + | </code> | ||
| + | Use the keyword var (or const ) followed by parentheses with each variable on its own line. | ||
| ==== Constantes ==== | ==== Constantes ==== | ||
| <code> | <code> | ||
| Línea 151: | Línea 160: | ||
| x := [5]int{2: 10, 4: 40} // [0 0 10 0 40] | x := [5]int{2: 10, 4: 40} // [0 0 10 0 40] | ||
| </code> | </code> | ||
| + | |||
| + | For example, while ''arr[0:5]'' returns [1,2,3,4,5] , ''arr[1:4]'' returns [2,3,4] . ''arr[0:]'' is the same as ''arr[0:len(arr)]'' , ''arr[:5]'' is the same as ''arr[0:5]'', and ''arr[:]'' is the same as ''arr[0:len(arr)]'' . | ||
| + | |||
| === Slices === | === Slices === | ||
| Línea 508: | Línea 520: | ||
| </code> | </code> | ||
| + | === Pointers === | ||
| + | |||
| + | <code> | ||
| + | func one(xPtr *int) { | ||
| + | *xPtr = 1 | ||
| + | } | ||
| + | func main() { | ||
| + | xPtr := new(int) | ||
| + | one(xPtr) | ||
| + | fmt.Println(*xPtr) // x is 1 | ||
| + | } | ||
| + | </code> | ||
| ==== Interfaces ==== | ==== Interfaces ==== | ||
| Línea 597: | Línea 621: | ||
| runtime.GOMAXPROCS(1) | runtime.GOMAXPROCS(1) | ||
| </code> | </code> | ||
| + | |||
| + | ==== Channels ==== | ||
| + | Sometimes there is a need for communication among goroutines for sending and receiving data, hence the need for synchronization among goroutines. In many programming environments, communication among concurrent programs is complex or limited with features. Go allows you to communicate among goroutines using channels that enable the synchronization of goroutine execution. The built-in make function is used to declare a channel with the help of the keyword chan, followed by the type for specifying the type of data you are using for exchanging data. | ||
| + | |||
| + | A channel of integer type is declared, so integer values will be passed into channels. | ||
| + | <code> | ||
| + | // Unbuffered channel of integers. | ||
| + | count := make(chan int) | ||
| + | // Buffered channel of integers for buffering up to 10 values. | ||
| + | count:= make(chan int, 10) | ||
| + | </code> | ||
| + | |||
| + | When buffered channels are declared, the capacity of channels to hold the data must be specified. If you | ||
| + | try to send more data than its capacity, you get an error. | ||
| + | |||
| + | === Unbuffered === | ||
| + | |||
| + | Unbuffered channels provide synchronous communication among goroutines, which ensures message delivery among them. With unbuffered channels, message sending is permitted only if there is a corresponding receiver that is ready to receive the messages. In this case, both sides of the channel have | ||
| + | to wait until the other side is ready for sending and receiving messages. With buffered channels, a limited | ||
| + | number of messages can be sent into the channel without a corresponding concurrent receiver for receiving those messages. After the messages are sent into buffered channels, those messages from the channel are received. Unlike unbuffered channels, message delivery can’t be guaranteed with buffered channels. | ||
| + | |||
| + | <code> | ||
| + | // Buffered channel of strings. | ||
| + | messages := make(chan string, 2) | ||
| + | // Send a message into the channel. | ||
| + | messages <- "Golang" | ||
| + | </code> | ||
| + | |||
| + | <code> | ||
| + | count := make(chan int) | ||
| + | wg.Add(2) | ||
| + | go printCounts("A", count) | ||
| + | go printCounts("B", count) | ||
| + | count <- 1 | ||
| + | // ... | ||
| + | func printCounts(label string, count chan int) { | ||
| + | defer wg.Done() | ||
| + | for { | ||
| + | val, ok := <-count | ||
| + | if !ok { | ||
| + | fmt.Println("Channel was closed") | ||
| + | return | ||
| + | } | ||
| + | fmt.Printf("Count: %d received from %s \n", val, label) | ||
| + | if val == 10 { | ||
| + | fmt.Printf("Channel Closed from %s \n", label) | ||
| + | close(count) | ||
| + | return | ||
| + | } | ||
| + | val++ | ||
| + | count <- val | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | === Buffered channels === | ||
| + | |||
| + | <code> | ||
| + | func main() { | ||
| + | messages := make(chan string, 2) | ||
| + | messages <- "Golang" | ||
| + | messages <- "Gopher" | ||
| + | //Recieve value from buffered channel | ||
| + | fmt.Println(<-messages) | ||
| + | fmt.Println(<-messages) | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | It is a simple example program that demonstrates a buffer channel without having any | ||
| + | goroutines. It creates a messages channel for buffering up to two string values. Values are sent into the | ||
| + | channel until its capacity of two. Because this channel is buffered, values can be sent without depending | ||
| + | on a receiver receiving them. If you try to add more values than its capacity, you will get an error. Once the values are sent into the buffered channel, they can be received from the channel. | ||
| + | |||
| + | ===== No so basic ===== | ||
| + | ==== Annotations (or struct tags) ==== | ||
| + | |||
| + | ===== Standard library ===== | ||
| + | ==== Strings ==== | ||
| + | ==== Dates ==== | ||
| + | <code> | ||
| + | time.Date(1970, time.January, 10, 0, 0, 0, 0, time.UTC) | ||
| + | </code> | ||
| + | ==== Time ==== | ||
| + | <code> | ||
| + | time.Sleep(time.Duration(sleep) * time.Millisecond) | ||
| + | </code> | ||
| + | |||
| + | ==== Rand ==== | ||
| + | <code> | ||
| + | sleep := rand.Int63n(1000) | ||
| + | </code> | ||
| + | |||
| + | ===== Notes ===== | ||
| + | ==== Install last version ==== | ||
| + | |||
| + | <code> | ||
| + | wget https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz | ||
| + | sudo tar -xvf go1.9.2.linux-amd64.tar.gz | ||
| + | sudo mv go /usr/local | ||
| + | export GOROOT=/usr/local/go | ||
| + | sudo ln -s /usr/local/go/bin/go /usr/bin/go | ||
| + | sudo ln -s /usr/local/go/bin/godoc /usr/bin/godoc | ||
| + | sudo ln -s /usr/local/go/bin/gofmt /usr/bin/gofmt | ||
| + | </code> | ||
| + | |||
| + | ==== Config VS Code to develop in Go ==== | ||
| + | You will need to install the 'golang' package. Also, when it is enabled, let it install the other tools. | ||
| + | |||
| + | If you wanted to debug you should change into the configuration the next variable (specially if only had a main.go file): | ||
| + | <code> | ||
| + | "program": "${workspaceRoot}", | ||
| + | </code> | ||
| + | A full example is: | ||
| + | <code> | ||
| + | { | ||
| + | // Use IntelliSense to learn about possible attributes. | ||
| + | // Hover to view descriptions of existing attributes. | ||
| + | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
| + | "version": "0.2.0", | ||
| + | "configurations": [ | ||
| + | { | ||
| + | "name": "Launch", | ||
| + | "type": "go", | ||
| + | "request": "launch", | ||
| + | "mode": "auto", | ||
| + | "program": "${workspaceRoot}", | ||
| + | "env": {}, | ||
| + | "args": [], | ||
| + | "showLog": true | ||
| + | } | ||
| + | ] | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | |||
| + | ====== Go Web programming ====== | ||
| + | ===== Basics ===== | ||
| + | ==== Http server ==== | ||
| + | <code> | ||
| + | package main | ||
| + | import ( | ||
| + | "net/http" | ||
| + | ) | ||
| + | func main() { | ||
| + | mux := http.NewServeMux() | ||
| + | fs := http.FileServer(http.Dir("public")) | ||
| + | mux.Handle("/", fs) | ||
| + | http.ListenAndServe(":8080", mux) | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | |||
| + | |||
| + | ====== Go Libraries ====== | ||
| + | ===== GORM ===== | ||
| + | * ''go get -u github.com/jinzhu/gorm'' | ||
| + | * ''go get -u github.com/go-sql-driver/mysql'' | ||
| + | |||
| + | <code> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | "github.com/jinzhu/gorm" | ||
| + | _ "github.com/jinzhu/gorm/dialects/mysql" | ||
| + | "fmt" | ||
| + | ) | ||
| + | |||
| + | type Person struct { | ||
| + | ID uint `json:"id""` | ||
| + | FirstName string `json:"firstname"` | ||
| + | LastName string `json:"lastname""` | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | db, err := gorm.Open("mysql", "root:pass@/test?charset=utf8&parseTime=True&loc=Local") | ||
| + | if err != nil { | ||
| + | fmt.Println(err) | ||
| + | } | ||
| + | defer db.Close() | ||
| + | |||
| + | db.AutoMigrate(&Person{}) | ||
| + | |||
| + | p1 := Person{FirstName: "John", LastName: "Doe"} | ||
| + | p2 := Person{FirstName: "Jane", LastName: "Smith"} | ||
| + | |||
| + | db.Create(&p1) | ||
| + | db.Create(&p2) | ||
| + | |||
| + | var p3 Person | ||
| + | db.First(&p3) | ||
| + | |||
| + | fmt.Println(p1.LastName) | ||
| + | fmt.Println(p2.LastName) | ||
| + | fmt.Println(p3.LastName) | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | ===== Gin ===== | ||
| + | * ''go get github.com/gin-gonic/gin'' | ||
| + | <code> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | "github.com/gin-gonic/gin" | ||
| + | "fmt" | ||
| + | ) | ||
| + | |||
| + | func main() { | ||
| + | r := gin.Default() | ||
| + | r.GET("/", func(c *gin.Context) { | ||
| + | c.JSON(200, gin.H{ | ||
| + | "message": "Hello World", | ||
| + | }) | ||
| + | }) | ||
| + | r.Run() | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | ==== Examble GORM + GIN ==== | ||
| + | * [[go_lib:examples:gormgin]] | ||
| + | |||