ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ ΠΏΡΠ±Π»ΠΈΠΊΡΠ΅ΡΡΡ Ρ ΡΠΎΠΊΡΠ°ΡΠ΅Π½ΠΈΡΠΌΠΈ, Π°Π²ΡΠΎΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ Stefan Nilsson.
ΠΡΠ½ΠΎΠ²Ρ
The Go Playground β ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΠΉ Π²Π΅Π±-ΡΠ΅ΡΠ²ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π² ΠΏΠ΅ΡΠΎΡΠ½ΠΈΡΠ΅ Π½Π΅Π±ΠΎΠ»ΡΡΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² Π΄ΡΡ Π΅ Β«Hello world!Β». ΠΠΎΠΏΡΠΎΠ±ΡΠΉΡΠ΅!
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
ΠΠ·ΡΡΠΈΡΠ΅ ΠΎΡΠ½ΠΎΠ²Ρ Go
A Tour of Go β Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΡΠ΅Π±Π½ΠΈΠΊ Ρ ΠΊΡΡΠ΅ΠΉ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ². ΠΠ½ Π±Π΅ΡΠ΅Ρ Π½Π°ΡΠ°Π»ΠΎ Π½Π° ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΌ ΡΠ°ΠΉΡΠ΅ ΠΈ ΠΎΠ±ΡΡΠ°Π΅Ρ Π²Π°Ρ ΠΎΡΠ½ΠΎΠ²Π°ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Go Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅.
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Go
Π Getting Started ΠΎΠ±ΡΡΡΠ½ΡΠ΅ΡΡΡ, ΠΊΠ°ΠΊ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Go. ΠΠΎΡΡΡΠΏΠ½Ρ Π±ΠΈΠ½Π°ΡΠ½ΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ Π΄Π»Ρ FreeBSD, Linux, Mac OS X ΠΈ Windows, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΠΏΠΎ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΡ ΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠ΅.
ΠΠ°ΡΠ½ΠΈΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ Go
How to Write Go Code ΠΏΠΎΡΠ²ΡΡΠ΅Π½ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΏΡΠΎΡΡΡΡ
ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² Go. ΠΠ½ ΡΠ°ΡΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΏΡΠΎ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ ΠΈ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π°, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ fetch
,
build
ΠΈ install
.
ΠΠΎΡΡΡΠΈΠ½Ρ
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ Π½ΠΎΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ (Π³ΠΎΡΡΡΠΈΠ½Ρ) Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° go. ΠΡΠ΅ Π³ΠΎΡΡΡΠΈΠ½Ρ Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΠΎΠ΄Π½ΠΎ ΠΈ ΡΠΎ ΠΆΠ΅ Π°Π΄ΡΠ΅ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ.
go list.Sort() //Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ list.Sort ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎ, Π±Π΅Π· ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Β«Hello from main goroutineΒ». ΠΠ½Π° ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°ΡΡ Β«Hello from another goroutineΒ», Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊΠ°Ρ ΠΈΠ· Π΄Π²ΡΡ Π³ΠΎΡΡΡΠΈΠ½ Π·Π°Π²Π΅ΡΡΠΈΡΡΡ ΠΏΠ΅ΡΠ²ΠΎΠΉ.
func main() {
go fmt.Println("Hello from another goroutine")
fmt.Println("Hello from main goroutine")
// Π ΡΡΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΠΈ ΡΠ±ΠΈΠ²Π°ΡΡΡΡ Π²ΡΠ΅
// Π°ΠΊΡΠΈΠ²Π½ΡΠ΅ Π³ΠΎΡΡΡΠΈΠ½Ρ
}
Π‘Π»Π΅Π΄ΡΡΡΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ Π²ΡΠ²Π΅Π΄Π΅Ρ Β«Hello from main goroutineΒ» ΠΈ Β«Hello from another goroutineΒ». ΠΠ½ΠΈ ΠΌΠΎΠ³ΡΡ ΠΏΠΎΡΠ²ΠΈΡΡΡΡ Π² Π»ΡΠ±ΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅. ΠΡΠ΅ ΠΎΠ΄Π½Π° ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ Π²ΡΠΎΡΠ°Ρ Π³ΠΎΡΡΡΠΈΠ½Π° ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΎΡΠ΅Π½Ρ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΈ Π½Π΅ ΠΏΠ΅ΡΠ°ΡΠ°Π΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ.
func main() {
go fmt.Println("Hello from another goroutine")
fmt.Println("Hello from main goroutine")
time.Sleep(time.Second) // Π΄Π°Π΄ΠΈΠΌ Π΄ΡΡΠ³ΠΎΠΉ Π³ΠΎΡΠΎΡΡΠΈΠ½Π΅ Π²ΡΠ΅ΠΌΡ Π·Π°Π²Π΅ΡΡΠΈΡΡΡΡ
}
ΠΠΎΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅Π°Π»ΠΈΡΡΠΈΡΠ½ΡΠΉ
ΠΏΡΠΈΠΌΠ΅Ρ, Π³Π΄Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ concurrency
Π΄Π»Ρ ΠΎΡΡΡΠΎΡΠΊΠΈ
ΡΠΎΠ±ΡΡΠΈΡ:
// Publish ΠΏΠ΅ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅ΠΊΡΡ Π² stdout ΠΏΠΎ ΠΈΡΡΠ΅ΡΠ΅Π½ΠΈΠΈ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ.
// ΠΠ½ Π½Π΅ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ ΠΈ ΡΡΠ°Π·Ρ ΠΆΠ΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ.
func Publish(text string, delay time.Duration) {
go func() {
time.Sleep(delay)
fmt.Println("BREAKING NEWS:", text)
}() // ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΊΡΡΠ³Π»ΡΠ΅ ΡΠΊΠΎΠ±ΠΊΠΈ. ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΡΠ·Π²Π°ΡΡ
// Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ.
}
ΠΠΎΡ ΠΊΠ°ΠΊ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ Publish
:
func main() {
Publish("A goroutine starts a new thread.", 5*time.Second)
fmt.Println("Letβs hope the news will published before I leave.")
// ΠΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡΡ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ Π½ΠΎΠ²ΠΎΡΡΠ΅ΠΉ
time.Sleep(10 * time.Second)
fmt.Println("Ten seconds later: Iβm leaving now.")
}
Π‘ΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°Π΅Ρ ΡΡΠΈ ΡΡΡΠΎΠΊΠΈ Π² Π·Π°Π΄Π°Π½Π½ΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅ Ρ ΠΏΡΡΠΈΡΠ΅ΠΊΡΠ½Π΄Π½ΡΠΌΠΈ ΠΏΠ΅ΡΠ΅ΡΡΠ²Π°ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρ Π½ΠΈΠΌΠΈ.
$ go run publish1.go
Letβs hope the news will published before I leave.
BREAKING NEWS: A goroutine starts a new thread.
Ten seconds later: Iβm leaving now.
ΠΠ΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ Β«ΡΠ½Π°Β», Π½ΠΎ Π΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ β ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»ΠΎΠ².
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
ΠΠ½ΡΡΡΠΈ Π³ΠΎΡΡΡΠΈΠ½Ρ Π΄Π΅ΠΉΡΡΠ²ΡΡΡ ΠΊΠ°ΠΊ ΠΊΠΎΡΡΡΠΈΠ½Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΡΡΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ. ΠΡΠ»ΠΈ ΠΎΠ΄Π½Π° Π³ΠΎΡΡΡΠΈΠ½Π° Π±Π»ΠΎΠΊΠΈΡΡΠ΅Ρ ΠΏΠΎΡΠΎΠΊ ΠΠ‘, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΎΠΆΠΈΠ΄Π°Ρ Π²Π²ΠΎΠ΄Π°, Π΄ΡΡΠ³ΠΈΠ΅ Π³ΠΎΡΡΡΠΈΠ½Ρ Π² ΡΡΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅ Π±ΡΠ΄ΡΡ ΠΌΠΈΠ³ΡΠΈΡΠΎΠ²Π°ΡΡ, ΡΡΠΎΠ±Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ.
ΠΠ°Π½Π°Π»Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΡΠ²ΡΠ·Ρ
ΠΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π°
ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ make
.
// Π½Π΅Π±ΡΡΠ΅ΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠ°Π½Π°Π» int-ΠΎΠ²
ic := make(chan int)
// Π±ΡΡΠ΅ΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠ°Π½Π°Π» Π½Π° 10 ΡΡΡΠΎΠΊ
sc := make(chan string, 10)
Π§ΡΠΎΠ±Ρ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π²
ΠΊΠ°Π½Π°Π», ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Π±ΠΈΠ½Π°ΡΠ½ΡΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ Β«<-
Β», Π° Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ β ΡΠ½Π°ΡΠ½ΡΠΉ
ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ.
ic <- 3 // ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ 3 Π² ΠΊΠ°Π½Π°Π»
n := <-sc // ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΡΡΠΎΠΊΡ ΠΈΠ· ΠΊΠ°Π½Π°Π»Π°
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ Π·Π°Π΄Π°Π΅Ρ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π° Π½Π° ΠΎΡΠΏΡΠ°Π²ΠΊΡ ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΊΠ°Π½Π°Π» ΡΠ²Π»ΡΠ΅ΡΡΡ Π΄Π²ΡΠ½Π°ΠΏΡΠ°Π²Π»Π΅Π½Π½ΡΠΌ.
chan Sushi // ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΡΠΈΠΏΠ° Sushi
chan<- string // ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΡΡΠΎΠΊ
<-chan int // ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ int
ΠΡΡΠ΅ΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠ΅ ΠΈ Π½Π΅Π±ΡΡΠ΅ΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠ΅ ΠΊΠ°Π½Π°Π»Ρ
- ΠΡΠ»ΠΈ ΠΏΡΠΎΠΏΡΡΠΊΠ½Π°Ρ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡ ΠΊΠ°Π½Π°Π»Π° ΡΠ°Π²Π½Π° Π½ΡΠ»Ρ ΠΈΠ»ΠΈ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ, ΠΊΠ°Π½Π°Π» Π½Π΅ Π±ΡΡΠ΅ΡΠΈΠ·ΡΠ΅ΡΡΡ ΠΈ ΠΎΡΠΏΡΠ°Π²ΠΈΡΠ΅Π»Ρ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΏΠΎΠ»ΡΡΠ°ΡΠ΅Π»Ρ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅.
- ΠΡΠ»ΠΈ ΠΊΠ°Π½Π°Π» ΠΈΠΌΠ΅Π΅Ρ Π±ΡΡΠ΅Ρ, ΠΎΡΠΏΡΠ°Π²ΠΈΡΠ΅Π»Ρ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄ΠΎ ΡΠ΅Ρ
ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΎ Π² Π±ΡΡΠ΅Ρ. ΠΡΠ»ΠΈ Π±ΡΡΠ΅Ρ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, ΠΆΠ΄Π΅ΠΌ ΠΏΠΎΠΊΠ° ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»ΡΡΠ°ΡΠ΅Π»Ρ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅.
- ΠΡΠΈΠ΅ΠΌΠ½ΠΈΠΊΠΈ Π²ΡΠ΅Π³Π΄Π° Π±Π»ΠΎΠΊΠΈΡΡΡΡΡΡ, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΠΎΡΠ²ΡΡΡΡ Π΄Π°Π½Π½ΡΠ΅ Π΄Π»Ρ ΠΏΡΠΈΠ΅ΠΌΠ°.
- ΠΡΠΏΡΠ°Π²ΠΊΠ° ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ Ρ nil-ΠΊΠ°Π½Π°Π»Π° Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π½Π°Π²ΡΠ΅Π³Π΄Π°.
ΠΠ°ΠΊΡΡΡΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π°
Π€ΡΠ½ΠΊΡΠΈΡ Π·Π°ΠΊΡΡΡΠΈΡ ΠΏΠΎΠΌΠ΅ΡΠ°Π΅Ρ, ΡΡΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π±ΡΠ΄ΡΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΏΠΎ ΠΊΠ°Π½Π°Π»Ρ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π·Π°ΠΊΡΡΠ²Π°ΡΡ ΠΊΠ°Π½Π°Π» Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ ΠΏΡΠΈΠ΅ΠΌΠ½ΠΈΠΊ ΡΡΠΎΠ³ΠΎ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ.
- ΠΠΎΡΠ»Π΅ Π²ΡΠ·ΠΎΠ²Π°
close
ΠΈ ΠΏΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π»ΡΠ±ΡΡ ΡΠ°Π½Π΅Π΅ ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½Π½ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ, ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΏΡΠΈΠ΅ΠΌΠ° Π²Π΅ΡΠ½ΡΡ Π½ΡΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ. - ΠΠΏΠ΅ΡΠ°ΡΠΈΡ ΠΏΡΠΈΠ΅ΠΌΠ° ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π°.
- ΠΡΠΏΡΠ°Π²ΠΊΠ° Π² Π·Π°ΠΊΡΡΡΡΠΉ ΠΊΠ°Π½Π°Π» ΠΈΠ»ΠΈ Π΅Π³ΠΎ Π·Π°ΠΊΡΡΡΠΈΠ΅, Π° ΡΠ°ΠΊΠΆΠ΅ Π·Π°ΠΊΡΡΡΠΈΠ΅ nil-ΠΊΠ°Π½Π°Π»Π°, Π²ΡΠ·ΠΎΠ²ΡΡ
run-time panic
.
ch := make(chan string)
go func() {
ch <- "Hello!"
close(ch)
}()
fmt.Println(<-ch) // Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°Π΅Ρ Β«Hello!Β»
fmt.Println(<-ch) // Π²ΡΠ²Π΅Π΄Π΅Ρ Π½ΡΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ «» Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ
fmt.Println(<-ch) // Π΅ΡΠ΅ ΡΠ°Π· Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°Π΅Ρ Β«Β»
v, ok := <-ch // v - ΡΡΠΎ «», ok β false
// ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΎΡ ch Π΄ΠΎ Π·Π°ΠΊΡΡΡΠΈΡ
for v := range ch {
fmt.Println(v) // Π½Π΅ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡΡ
}
ΠΡΠΈΠΌΠ΅Ρ
Π ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΡ
Publish
Π²Π΅ΡΠ½Π΅Ρ ΠΊΠ°Π½Π°Π», ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π±ΡΠΎΠ°Π΄ΠΊΠ°ΡΡΠΈΠ½Π³Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅
ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΡΠ΅ΠΊΡΡΠ°:
// Publish Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅ΠΊΡΡ Π² stdout ΠΏΠΎ ΠΈΡΡΠ΅ΡΠ΅Π½ΠΈΠΈ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ.
// ΠΠΎΠ³Π΄Π° ΡΠ΅ΠΊΡΡ Π±ΡΠ΄Π΅Ρ ΠΎΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½, Π·Π°ΠΊΡΡΠ²Π°Π΅ΠΌ ΠΊΠ°Π½Π°Π», ΠΊΠΎΡΠΎΡΡΠΉ Π½Π° Β«ΠΏΠ°ΡΠ·Π΅Β».
func Publish(text string, delay time.Duration) (wait <-chan struct{}) {
ch := make(chan struct{})
go func() {
time.Sleep(delay)
fmt.Println(text)
close(ch)
}()
return ch
}
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΊΠ°Π½Π°Π» ΠΏΡΡΡΡΡ ΡΡΡΡΠΊΡΡΡ Π΄Π»Ρ ΡΠΊΠ°Π·Π°Π½ΠΈΡ, ΡΡΠΎ ΠΊΠ°Π½Π°Π» Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ, Π° Π½Π΅ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π°Π½Π½ΡΡ . ΠΡΠ³Π»ΡΠ΄ΠΈΡ ΡΡΠΎ ΡΠ°ΠΊ:
wait := Publish("important news", 2 * time.Minute)
// Π²ΡΠΏΠΎΠ»Π½ΠΈΠΌ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ
<-wait // Π² Π±Π»ΠΎΠΊΠ΅, ΠΏΠΎΠΊΠ° ΡΠ΅ΠΊΡΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΎΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½
Select ΠΎΠΆΠΈΠ΄Π°Π΅Ρ Π³ΡΡΠΏΠΏΡ ΠΊΠ°Π½Π°Π»ΠΎΠ²
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ select
ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ
ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ.
- ΠΠΏΠ΅ΡΠ°ΡΠΎΡ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΎΠ΄Π½Π° ΠΈΠ· ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π°.
- ΠΡΠ»ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ, ΡΠΎ ΠΎΠ΄Π½Π° ΠΈΠ· Π½ΠΈΡ
Π±ΡΠ΄Π΅Ρ Π²ΡΠ±ΡΠ°Π½Π° ΡΠ»ΡΡΠ°ΠΉΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ.
// Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ
ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π΄Π°Π½Π½ΡΠ΅ Π½Π΅ ΠΏΠΎΡΠ²ΡΡΡΡ Π² ch1 ΠΈΠ»ΠΈ ch2
select {
case <-ch1:
fmt.Println("Received from ch1")
case <-ch2:
fmt.Println("Received from ch2")
}
ΠΠΏΠ΅ΡΠ°ΡΠΈΠΈ
ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈ ΠΏΡΠΈΠ΅ΠΌΠ° Π² nil-ΠΊΠ°Π½Π°Π»Π΅
Π±Π»ΠΎΠΊΠΈΡΡΡΡΡΡ Π½Π°Π²ΡΠ΅Π³Π΄Π°. ΠΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊΠ°Π½Π°Π»Π° Π² ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ
select
:
ch1 = nil // ΠΎΡΠΊΠ»ΡΡΠ°Π΅Ρ ΡΡΠΎΡ ΠΊΠ°Π½Π°Π»
select {
case <-ch1:
fmt.Println("Received from ch1") // Π½Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ
case <-ch2:
fmt.Println("Received from ch2")
}
ΠΠ°ΡΠΈΠ°Π½Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ
ΠΠ°ΡΠΈΠ°Π½Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½, Π΅ΡΠ»ΠΈ Π²ΡΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Ρ.
// Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ
select {
case x := <-ch:
fmt.Println("Received", x)
default:
fmt.Println("Nothing available")
}
ΠΡΠΈΠΌΠ΅ΡΡ
ΠΠ΅ΡΠΊΠΎΠ½Π΅ΡΠ½Π°Ρ ΡΠ»ΡΡΠ°ΠΉΠ½Π°Ρ Π΄Π²ΠΎΠΈΡΠ½Π°Ρ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ
Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ»ΡΡΠ°ΠΉΠ½ΡΠΉ Π²ΡΠ±ΠΎΡ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³ΡΡ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ»ΡΡΠ°ΠΉΠ½ΡΠ΅ Π±ΠΈΡΡ.
rand := make(chan int)
for {
select {
case rand <- 0: // no statement
case rand <- 1:
}
}
ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΠΏΠΎ ΡΠ°ΠΉΠΌΠ°ΡΡΡ
Π€ΡΠ½ΠΊΡΠΈΡ time.After
Π²Ρ
ΠΎΠ΄ΠΈΡ Π² ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ. ΠΠ½Π° ΠΎΠΆΠΈΠ΄Π°Π΅Ρ ΠΈΡΡΠ΅ΡΠ΅Π½ΠΈΡ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ
Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π° Π·Π°ΡΠ΅ΠΌ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ΅ΠΊΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ Π² Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΠΉ ΠΊΠ°Π½Π°Π»:
select {
case news := <-AFP:
fmt.Println(news)
case <-time.After(time.Minute):
fmt.Println("Time out: No news in one minute")
}
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ select
Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ
ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ case
Π½Π΅ ΡΠΌΠΎΠΆΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡΡΡ. Π‘ Π½ΡΠ»Π΅Π²ΡΠΌΠΈ ΠΊΠ΅ΠΉΡΠ°ΠΌΠΈ ΡΡΠΎΠ³ΠΎ
Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ:
select {}
ΠΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ
Π’Π°ΠΊΠ°Ρ ΡΠΈΡΡΠ°ΡΠΈΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ ΡΠ°ΡΡΠΎ ΠΈ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ»ΠΎΠΆΠ½ΠΈΡΡ ΠΎΡΠ»Π°Π΄ΠΊΡ.
ΠΠΎΠΊΠ°Π·Π°Π½Π½Π°Ρ Π½ΠΈΠΆΠ΅ ΡΡΠ½ΠΊΡΠΈΡ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ Π³ΠΎΠ½ΠΊΠ΅ Π΄Π°Π½Π½ΡΡ , ΠΈ Π΅Π΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π½Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΎ β ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°ΡΡ ΡΠΈΡΠ»ΠΎ 1. ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π²ΡΡΡΠ½ΠΈΡΡ, ΠΊΠ°ΠΊ ΡΡΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ:
func race() {
wait := make(chan struct{})
n := 0
go func() {
n++ // ΡΡΠ΅Π½ΠΈΠ΅, ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅, Π·Π°ΠΏΠΈΡΡ
close(wait)
}()
n++ // ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΡΡΡΠΈΠΉ Π΄ΠΎΡΡΡΠΏ
<-wait
fmt.Println(n) // ΠΡΠ²ΠΎΠ΄: <unspecified>
}
ΠΠ²Π΅ Π³ΠΎΡΡΡΠΈΠ½Ρ g1 ΠΈ g2, ΡΡΠ°ΡΡΠ²ΡΡΡ Π² Π³ΠΎΠ½ΠΊΠ΅, ΠΈ Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΡΠΏΠΎΡΠΎΠ±Π° ΡΠ·Π½Π°ΡΡ, Π² ΠΊΠ°ΠΊΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅ Π±ΡΠ΄ΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ. ΠΠΈΠΆΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ²:

ΠΠ°ΠΊ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ Π³ΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ ?
ΠΡΠ΅Π΄ΠΏΠΎΡΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ Π΄Π°Π½Π½ΡΠΌ Π² Go β ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠ°Π½Π°Π» Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π°Π½Π½ΡΡ ΠΎΡ ΠΎΠ΄Π½ΠΎΠΉ Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΊ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ.
func sharingIsCaring() {
ch := make(chan int)
go func() {
n := 0 // ΠΠΎΠΊΠ°Π»ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π²ΠΈΠ΄Π½Π° ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΠΏΠ΅ΡΠ²ΠΎΠΉ Π³ΠΎΡΡΡΠΈΠ½Ρ
n++
ch <- n // ΠΠ°Π½Π½ΡΠ΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΈΠ· ΠΏΠ΅ΡΠ²ΠΎΠΉ Π³ΠΎΡΡΡΠΈΠ½Ρ
}()
n := <-ch // ...ΠΈ Π±Π»Π°Π³ΠΎΠΏΠΎΠ»ΡΡΠ½ΠΎ ΠΏΡΠΈΠ±ΡΠ²Π°ΡΡ Π²ΠΎ Π²ΡΠΎΡΡΡ
n++
fmt.Println(n) // ΠΡΠ²ΠΎΠ΄: 2
}
Π ΡΡΠΎΠΌ ΠΊΠΎΠ΄Π΅ ΠΊΠ°Π½Π°Π»Π° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΡΡ Π΄Π²Π° ΡΠΎΠ±ΡΡΠΈΡ:
- ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΎΡ ΠΎΠ΄Π½ΠΎΠΉ Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΊ Π΄ΡΡΠ³ΠΎΠΉ β ΡΠΎΡΠΊΠ° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ;
- ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠ°Ρ Π³ΠΎΡΡΡΠΈΠ½Π° Π±ΡΠ΄Π΅Ρ ΠΆΠ΄Π°ΡΡ, ΠΏΠΎΠΊΠ° Π΄ΡΡΠ³Π°Ρ ΠΏΠΎΠ»ΡΡΠΈΡ Π΄Π°Π½Π½ΡΠ΅ ΠΈ Π½Π°ΠΎΠ±ΠΎΡΠΎΡ.
ΠΠ°ΠΊ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ Π³ΠΎΠ½ΠΊΡ Π΄Π°Π½Π½ΡΡ ?
ΠΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ ΠΌΠΎΠ³ΡΡ Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΡΠ²Π»ΡΡΡΡΡ, Π½ΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ ΠΈΡ ΡΡΡΠ΄Π½ΠΎ. Π ΡΡΠ°ΡΡΡΡ ΡΡΠ΅Π΄Π° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Go ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠΌΠΎΡΡ ΠΈ Π² ΡΡΠΎΠΌ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΊΠ»ΡΡ -race Π΄Π»Ρ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ Π΄Π΅ΡΠ΅ΠΊΡΠΎΡΠ° Π³ΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ .
$ go test -race [packages]
$ go run -race [packages]
ΠΡΠΈΠΌΠ΅Ρ
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Ρ Π³ΠΎΠ½ΠΊΠΎΠΉ Π΄Π°Π½Π½ΡΡ :
package main
import "fmt"
func main() {
i := 0
go func() {
i++ // Π·Π°ΠΏΠΈΡΡ
}()
fmt.Println(i) // ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΠΎΠ΅ ΡΡΠ΅Π½ΠΈΠ΅
}
ΠΠ°ΠΏΡΡΠΊ ΡΡΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ -race ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ Π½Π°ΠΌ, ΡΡΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π³ΠΎΠ½ΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρ Π·Π°ΠΏΠΈΡΡΡ Π² ΡΡΡΠΎΠΊΠ΅ 7 ΠΈ ΡΡΠ΅Π½ΠΈΠ΅ΠΌ Π² ΡΡΡΠΎΠΊΠ΅ 9:
$ go run -race main.go
0
==================
WARNING: DATA RACE
Write by goroutine 6:
main.main.func1()
/tmp/main.go:7 +0x44
Previous read by main goroutine:
main.main()
/tmp/main.go:9 +0x7e
Goroutine 6 (running) created at:
main.main()
/tmp/main.go:8 +0x70
==================
Found 1 data race(s)
exit status 66
ΠΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ
ΠΠ½ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π° darwin/amd64, freebsd/amd64, linux/amd64 ΠΈ Windows/amd64.
ΠΠ°ΠΊΠ»Π°Π΄Π½ΡΠ΅ ΡΠ°ΡΡ ΠΎΠ΄Ρ Π²Π°ΡΡΠΈΡΡΡΡΡΡ, Π½ΠΎ ΠΎΠ±ΡΡΠ½ΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ Π² 5-10 ΡΠ°Π· ΠΈ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π² 2-20 ΡΠ°Π·.
ΠΠ°ΠΊ ΠΎΡΠ»Π°ΠΆΠΈΠ²Π°ΡΡ deadlock-ΠΈ
ΠΡΠ΄Π»ΠΎΠΊΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡ, ΠΊΠΎΠ³Π΄Π° Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΆΠ΄ΡΡ Π΄ΡΡΠ³ Π΄ΡΡΠ³Π° ΠΈ Π½ΠΈ ΠΎΠ΄Π½Π° ΠΈΠ· Π½ΠΈΡ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π²Π΅ΡΡΠΈΡΡΡΡ.
ΠΠ·Π³Π»ΡΠ½Π΅ΠΌ Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ:
func main() {
ch := make(chan int)
ch <- 1
fmt.Println(<-ch)
}
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π·Π°ΡΡΡΡΠ½Π΅Ρ Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ, ΠΎΠΆΠΈΠ΄Π°Ρ Π²Π΅ΡΠ½ΠΎ, ΠΏΠΎΠΊΠ° ΠΊΡΠΎ-ΡΠΎ ΠΏΡΠΎΡΠΈΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅. Go ΡΠΏΠΎΡΠΎΠ±Π΅Π½ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΡΠΈΡΡΠ°ΡΠΈΠΈ Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ. ΠΠΎΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π½Π°ΡΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
.../deadlock.go:7 +0x6c
Π‘ΠΎΠ²Π΅ΡΡ ΠΏΠΎ ΠΎΡΠ»Π°Π΄ΠΊΠ΅
ΠΠΎΡΡΡΠΈΠ½Π° ΠΌΠΎΠΆΠ΅Ρ Π·Π°ΡΡΡΡΡΡ:
- ΠΊΠΎΠ³Π΄Π° ΠΎΠ½Π° ΠΆΠ΄Π΅Ρ ΠΊΠ°Π½Π°Π»;
- Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΎΠ½Π° ΠΆΠ΄Π΅Ρ ΠΎΠ΄Π½Ρ ΠΈΠ· Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΎΠΊ Π² ΠΏΠ°ΠΊΠ΅ΡΠ΅ sync.
ΠΠ±ΡΠΈΠ΅ ΠΏΡΠΈΡΠΈΠ½Ρ:
- Π½ΠΈ ΠΎΠ΄Π½Π° Π³ΠΎΡΡΡΠΈΠ½Π° Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΊΠ°Π½Π°Π»Ρ ΠΈΠ»ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ΅;
- Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΆΠ΄ΡΡ Π΄ΡΡΠ³ Π΄ΡΡΠ³Π°.
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠ°Π½Π°Π»ΠΎΠ² Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΠ½ΡΡΡ, ΡΡΠΎ Π²ΡΠ·Π²Π°Π»ΠΎ Π΄Π΅Π΄Π»ΠΎΠΊ. Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, ΠΈΠ½ΡΠ΅Π½ΡΠΈΠ²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΠ΅ ΠΌΡΡΡΠ΅ΠΊΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ ΡΡΡΠ΄Π½ΡΠΌΠΈ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ.
ΠΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π³ΠΎΡΡΡΠΈΠ½
ΠΡΡΠΏΠΏΠ° sync.WaitGroup
ΠΎΠΆΠΈΠ΄Π°Π΅Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ Π³ΡΡΠΏΠΏΡ Π³ΠΎΡΡΡΠΈΠ½:
var wg sync.WaitGroup
wg.Add(2)
go func() {
// Do work.
wg.Done()
}()
go func() {
// Do work.
wg.Done()
}()
wg.Wait()
- ΡΠ½Π°ΡΠ°Π»Π° ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ Π³ΠΎΡΡΡΠΈΠ½Π° Π²ΡΠ·ΡΠ²Π°Π΅Ρ Add, ΡΡΠΎΠ±Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΎΠΆΠΈΠ΄Π°ΡΡΠΈΡ Π³ΠΎΡΡΡΠΈΠ½;
- Π·Π°ΡΠ΅ΠΌ Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ Π΄Π²Π΅ Π½ΠΎΠ²ΡΠ΅ Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΈ Π²ΡΠ·ΡΠ²Π°ΡΡ Done ΠΏΡΠΈ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ.
Π ΡΠΎ ΠΆΠ΅ Π²ΡΠ΅ΠΌΡ Wait ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΡΡΠΈ Π΄Π²Π΅ Π³ΠΎΡΡΡΠΈΠ½Ρ Π½Π΅ Π·Π°Π²Π΅ΡΡΠ°ΡΡΡ.
ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅: Π³ΡΡΠΏΠΏΠ° ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΏΠΎΡΠ»Π΅ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ.
Π’ΡΠ°Π½ΡΠ»ΡΡΠΈΡ ΡΠΈΠ³Π½Π°Π»Π° ΠΏΠΎ ΠΊΠ°Π½Π°Π»Ρ
Π ΡΡΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΡ
Publish
Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΊΠ°Π½Π°Π», ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ ΡΠΈΠ³Π½Π°Π»Π° ΠΏΡΠΈ
ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ.
// ΠΏΠ΅ΡΠ°ΡΡ ΡΠ΅ΠΊΡΡΠ° ΠΏΠΎ ΠΈΡΡΠ΅ΡΠ΅Π½ΠΈΠΈ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ
// ΠΊΠΎΠ³Π΄Π° ΡΡΠΎ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ, ΠΊΠ°Π½Π°Π» ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ Π±ΡΠ΄Π΅Ρ Π·Π°ΠΊΡΡΡ
func Publish(text string, delay time.Duration) (wait <-chan struct{}) {
ch := make(chan struct{})
go func() {
time.Sleep(delay)
fmt.Println("BREAKING NEWS:", text)
close(ch) // ΡΡΠ°Π½ΡΠ»ΡΡΠΈΡ Π½Π° Π²ΡΠ΅ ΠΏΡΠΈΠ΅ΠΌΠ½ΠΈΠΊΠΈ
}()
return ch
}
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ ΠΌΡ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΊΠ°Π½Π°Π» ΠΏΡΡΡΡΡ
ΡΡΡΡΠΊΡΡΡ: struct{}
. ΠΡΠΎ ΡΠ²Π½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΠΎ, ΡΡΠΎ ΠΊΠ°Π½Π°Π» ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ, Π° Π½Π΅ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π°Π½Π½ΡΡ
.
ΠΠΎΡ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ:
func main() {
wait := Publish("Channels let goroutines communicate.", 5*time.Second)
fmt.Println("Waiting for news...")
<-wait
fmt.Println("Time to leave.")
}
Waiting for news...
BREAKING NEWS: Channels let goroutines communicate.
Time to leave.
ΠΠ°ΠΊ ΡΠ±ΠΈΡΡ Π³ΠΎΡΡΡΠΈΠ½Ρ
Π§ΡΠΎΠ±Ρ Π³ΠΎΡΡΡΠΈΠ½Π° ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΠ»Π°ΡΡ, Π΅ΠΉ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΎΡΠ»ΡΡΠΈΠ²Π°ΡΡ ΡΠΈΠ³Π½Π°Π» ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Π½Π° Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΠΎΠΌ Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ°Π½Π°Π»Π΅ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π΅Π³ΠΎ.
quit := make(chan bool)
go func() {
for {
select {
case <-quit:
return
default:
// β¦
}
}
}()
// β¦
quit <- true
ΠΠΎΡ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»Π½ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ, Π³Π΄Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΎΠ΄ΠΈΠ½ ΠΊΠ°Π½Π°Π» ΠΊΠ°ΠΊ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π°Π½Π½ΡΡ , ΡΠ°ΠΊ ΠΈ Π΄Π»Ρ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ:
// Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΊΠ°Π½Π°Π», ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ ΡΠΈΡΠ»Π° 1, 2, 3β¦
// ΡΡΠΎΠ±Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ Π³ΠΎΡΡΡΠΈΠ½Ρ, Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ
// Π½ΠΎΠΌΠ΅Ρ ΡΡΠΎΠΌΡ ΠΊΠ°Π½Π°Π»Ρ
func Generator() chan int {
ch := make(chan int)
go func() {
n := 1
for {
select {
case ch <- n:
n++
case <-ch:
return
}
}
}()
return ch
}
func main() {
number := Generator()
fmt.Println(<-number)
fmt.Println(<-number)
number <- 0 // ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ Π³ΠΎΡΡΡΠΈΠ½Ρ
fmt.Println(<-numberΠΌ) // ΠΎΡΠΈΠ±ΠΊΠ°, Π±ΠΎΠ»ΡΡΠ΅ Π½ΠΈΠΊΡΠΎ Π½Π΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ
}
1
2
fatal error: all goroutines are asleep - deadlock!
Timer ΠΈ Ticker
Π’Π°ΠΉΠΌΠ΅ΡΡ ΠΈ ΡΠΈΠΊΠ΅ΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΊΠΎΠ΄ ΠΏΠΎ ΡΠ°ΡΠΏΠΈΡΠ°Π½ΠΈΡ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π·.
Timeout (Timer)
time.After ΠΎΠΆΠΈΠ΄Π°Π΅Ρ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠ°, Π° Π·Π°ΡΠ΅ΠΌ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ΅ΠΊΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ ΠΏΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠΌΡ ΠΊΠ°Π½Π°Π»Ρ:
select {
case news := <-AFP:
fmt.Println(news)
case <-time.After(time.Hour):
fmt.Println("No news in an hour.")
}
time.Timer Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½ ΡΠ±ΠΎΡΡΠΈΠΊΠΎΠΌ ΠΌΡΡΠΎΡΠ° Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΡΠ°ΠΉΠΌΠ΅Ρ Π½Π΅ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ time.NewTimer Π²ΠΌΠ΅ΡΡΠΎ Π²ΡΠ·ΠΎΠ²Π° ΠΌΠ΅ΡΠΎΠ΄Π° Stop, ΠΊΠΎΠ³Π΄Π° ΡΠ°ΠΉΠΌΠ΅Ρ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ΅Π½:
for alive := true; alive; {
timer := time.NewTimer(time.Hour)
select {
case news := <-AFP:
timer.Stop()
fmt.Println(news)
case <-timer.C:
alive = false
fmt.Println("No news in an hour. Service aborting.")
}
}
Repeat (Ticker)
time.Tick
Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ
ΠΊΠ°Π½Π°Π», ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΡΠΈΠΊΠ°Π½ΡΠ΅ ΡΠ°ΡΠΎΠ² Ρ ΡΠ΅ΡΠ½ΡΠΌΠΈ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π°ΠΌΠΈ:
go func() {
for now := range time.Tick(time.Minute) {
fmt.Println(now, statusUpdate())
}
}()
time.Ticker Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½ ΡΠ±ΠΎΡΡΠΈΠΊΠΎΠΌ ΠΌΡΡΠΎΡΠ° Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΡΠ°ΠΉΠΌΠ΅Ρ Π½Π΅ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ time.NewTicker Π²ΠΌΠ΅ΡΡΠΎ Π²ΡΠ·ΠΎΠ²Π° ΠΌΠ΅ΡΠΎΠ΄Π° Stop, ΠΊΠΎΠ³Π΄Π° ΡΠΈΠΊΠ΅Ρ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ΅Π½:
func Foo() {
timer = time.AfterFunc(time.Minute, func() {
log.Println("Foo run for more than a minute.")
})
defer timer.Stop()
// Do heavy work
}
ΠΠ»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ (ΠΌΡΡΡΠ΅ΠΊΡ)
ΠΠ½ΠΎΠ³Π΄Π° ΡΠ΄ΠΎΠ±Π½Π΅Π΅ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ Π΄Π°Π½Π½ΡΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ²Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ, Π° Π½Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠ°Π½Π°Π»ΠΎΠ². Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Go ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ Π΄Π»Ρ ΡΡΠΎΠΉ ΡΠ΅Π»ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ sync.Mutex.
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Ρ ΠΎΡΡΠΎΡΠΎΠΆΠ½ΠΎΡΡΡΡ
ΠΠ·-Π·Π° ΡΡΠΎΠ³ΠΎ Π²Π°ΠΌ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΠΎΠ΄ΡΠΌΠ°ΡΡ ΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠΉ ΡΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ Ρ ΡΠΈΡΡΡΠΌ API ΠΈ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ Π²ΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π²Π½ΡΡΡΠΈ.
Π ΡΡΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ
Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΡ ΠΈ ΠΏΡΠΎΡΡΡΡ Π² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΡΡ ΡΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ
AtomicInt
, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Ρ
ΡΠ°Π½ΠΈΡΡΡ integer
. ΠΡΠ±ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π³ΠΎΡΡΡΠΈΠ½
ΠΌΠΎΠΆΠ΅Ρ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΡΠΎΠΌΡ ΡΠΈΡΠ»Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Add
ΠΈ Value
.
// AtomicInt β ΡΡΠΎ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½Π°Ρ ΡΡΡΡΠΊΡΡΡΠ° Π΄Π°Π½Π½ΡΡ
, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ°Ρ int
// Π΅Π³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ°Π²Π½ΠΎ 0
type AtomicInt struct {
mu sync.Mutex // Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ ΠΎΠ΄Π½ΠΎΠΉ Π³ΠΎΡΡΡΠΈΠ½ΠΎΠΉ Π·Π° ΡΠ°Π·
n int
}
// Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ n ΠΊ AtomicInt
func (a *AtomicInt) Add(n int) {
a.mu.Lock() // ΠΆΠ΄Π΅ΠΌ ΠΏΠΎΠΊΠ° Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡΡ
a.n += n
a.mu.Unlock() // ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ
}
// Value Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ a
func (a *AtomicInt) Value() int {
a.mu.Lock()
n := a.n
a.mu.Unlock()
return n
}
func main() {
wait := make(chan struct{})
var n AtomicInt
go func() {
n.Add(1) // ΠΎΠ΄ΠΈΠ½ Π΄ΠΎΡΡΡΠΏ
close(wait)
}()
n.Add(1) // Π΄ΡΡΠ³ΠΎΠΉ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΡΠΉ Π΄ΠΎΡΡΡΠΏ
<-wait
fmt.Println(n.Value()) // 2
}
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
ΠΡ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π»ΠΈ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½Π΅Π½Π½ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, ΠΎΡΠ½ΠΎΡΡΡΠΈΠ΅ΡΡ ΠΊ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΠΎΡΡΠΈ Π² Go. ΠΡΠΎ Π½Π΅ Π²Π΅ΡΡ ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π» ΠΏΠΎ ΡΠ΅ΠΌΠ΅ β ΠΎΡΡΠ°Π»ΡΠ½ΠΎΠ΅ Π²Π°ΠΌ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΠΈΠ·ΡΡΠ°ΡΡ Π½Π° ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΌ ΡΠ°ΠΉΡΠ΅. ΠΠ΅ Π»Π΅Π½ΠΈΡΠ΅ΡΡ, ΡΠ°Π·Π²ΠΈΠ²Π°ΠΉΡΠ΅ΡΡ ΠΈ ΡΠ΄Π°ΡΠΈ Π² ΠΎΠ±ΡΡΠ΅Π½ΠΈΠΈ!
ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»Ρ:
- ΠΠ΄Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠ·ΡΠΊ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Go?
- ΠΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΠΎΡΡΡ Π² Golang ΠΈ WorkerPool [Π§Π°ΡΡΡ 2]
- Golang ΠΏΡΠΎΡΠΈΠ² Python: ΠΊΠ°ΠΊΠΎΠΉ ΡΠ·ΡΠΊ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²ΡΠ±ΡΠ°ΡΡ?
- Π―Π·ΡΠΊ Go: ΠΊΠ°ΠΊ ΡΡΠ°ΡΡ Π²ΠΎΡΡΡΠ΅Π±ΠΎΠ²Π°Π½Π½ΡΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠΎΠΌ
ΠΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ