Golang download
Installation package link: https://share.weiyun.com/InsZoHHu
IDE download: https://www.jetbrains.com/go/
The first golang program
package main
import "fmt"
func main() {
fmt.Println("hello golang")
}
Every executable code must contain the three elements of Package, import and function.
variable
Main function file:
package main
import (
"awesomeProject/package1"
"fmt"
)
// 全局变量
var gStr string
var gInt int
func main() {
// 局部变量
var lStr string
var lInt int
gStr = "out"
gInt = 100
lStr = "in"
lInt = 50
fmt.Println(gStr)
fmt.Println(gInt)
fmt.Println(lStr)
fmt.Println(lInt)
// 包外函数
package1.Fun()
// 包外变量
package1.Str = "good"
fmt.Println(package1.Str)
}
The file of the package1 package:
package package1
import (
"fmt"
)
var Str string
func Fun() {
fmt.Println("test")
}
Note: golang uses the case of the first letter to distinguish whether it is visible outside the package.
So the Fun() function, Str, which wants to be accessed in the main file, is capitalized.
arrays, slices, dictionaries
package main
import "fmt"
func main() {
//数组初始化
var strAry = [10]string{"aa", "bb", "cc", "dd", "ee"}
//切片初始化
var sliceAry = make([]string, 0)
sliceAry = strAry[1:3]
//字典初始化
var dic = map[string]int{
"apple": 1,
"watermelon": 2,
}
// %v 是按照默认格式输出
fmt.Printf("strAry %+v\n", strAry)
fmt.Printf("sliceAry %+v\n", sliceAry)
fmt.Printf("dic %+v\n", dic)
}
Slices point to arrays by indexing. Slices can change the content of an element, but arrays cannot. In development, slices are mainly used for logic processing.
conditional statement
package main
import "fmt"
func main() {
// 可以通过 := 这种方式直接初始化基础变量
localStr := "case3"
if localStr == "case3" {
fmt.Printf("into ture logic\n")
} else {
fmt.Printf("into false logic\n")
}
//字典初始化
var dic = map[string]int{
"apple": 1,
"watermelon": 2,
}
// 用于检查字典中某个键是否存在,如果存在 num 取键值,ok 取 true,反之 ok 取 false
if num, ok := dic["orange"]; ok {
fmt.Printf("orange num %d\n", num)
}
if num, ok := dic["watermelon"]; ok {
fmt.Printf("watermelon num %d\n", num)
}
switch localStr {
case "case1":
fmt.Println("case1")
case "case2":
fmt.Println("case2")
case "case3":
fmt.Println("case3")
default:
fmt.Println("default")
}
}
cycle
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Printf("i = %d ", i)
}
fmt.Println("")
j := 0
for {
if j == 5 {
break
}
fmt.Printf("j = %d ", j)
j++
}
fmt.Println("")
// 可以指定初始个数也
var strAry = []string{"aa", "bb", "cc", "dd", "ee"}
//切片初始化
var sliceAry = make([]string, 0)
sliceAry = strAry[1:3]
for i, str := range sliceAry {
fmt.Printf("slice i %d, str %s ", i, str)
}
fmt.Println("")
//字典初始化
var dic = map[string]int{
"apple": 1,
"watermelon": 2,
}
for k, v := range dic {
fmt.Printf("key %s, value %d\n", k, v)
}
}
The range keyword is used to iterate over iterable data structures such as slices, arrays, and dictionaries.
coroutine
package main
import (
"fmt"
"time"
)
func a() {
time.Sleep(3 * time.Second)
fmt.Println("it's a")
}
func b() {
time.Sleep(2 * time.Second)
fmt.Println("it's b")
}
func c() {
time.Sleep(1 * time.Second)
fmt.Println("it's c")
}
func main() {
go a()
go b()
go c()
time.Sleep(5 * time.Second)
}
As long as the keyword go is used, the three functions a, b, and c can run concurrently.
channel
Key points for channels:
1. Similar to pipes in Linux, first-in-first-out; 2. Thread-safe, multiple goroutines access at the same time, no need to lock; 3. Channel is typed, and an integer channel can only store integers.
Channel definition:
var ch0 chan int
var ch1 chan string
var ch2 chan map[string]string
type stu struct{}
var ch3 chan stu
var ch4 chan *stu
Channels can be used to transfer data between coroutines, and are generally divided into buffered channels and unbuffered channels .
If there is data exchange between two coroutines, channels can be used to transfer them.
package main
import (
"fmt"
"time"
)
var ch chan int
func a() {
time.Sleep(3 * time.Second)
a := 5
ch <- a // 发送操作
fmt.Println("out of a")
}
func b() {
time.Sleep(1 * time.Second)
fromA := <-ch // 接收操作
b := fromA + 3
fmt.Println("b is ", b)
}
func main() {
ch = make(chan int, 1)
go a()
go b()
time.Sleep(20 * time.Second)
fmt.Println("out of main")
}
- make(chan int, 1) is used to create a new channel, where chan int indicates that the channel is used to transmit values of integer type.
- The 1 after the comma specifies the buffer size for the channel. The buffer size indicates the number of elements that the channel can hold at the same time. In this case, ch is a channel with a buffer size of 1, that is, it can hold at most one integer value at a time.
for example:
When creating a buffered channel, when a send operation (ch <- value) occurs, if the buffer is full, the send operation will be blocked until a receive operation (value = <- ch) reads a value from the buffer. Similarly, when a receive operation (value = <- ch ) occurs, if the buffer is empty, the receive operation will block until a send operation (ch <- value) puts a value into the buffer.
chSync := make(chan int) // 无缓冲
chAsyn := make(chan int, 1) // 有缓冲
Understanding buffered and unbuffered:
The same is to insert a data into the channel: chSync <-1 No buffering scenario : wait for another coroutine to take over this parameter through <-chSync, then chSync<-1 will continue, otherwise it will be blocked all the time . Buffered scenario : chAsyn<-1 will not block, because the buffer size is 1, only when the second value is put, the first one has not been taken away, then it will block. After careful understanding, this is actually the difference between synchronous and asynchronous. Without buffering, it must be synchronous waiting. With buffering, it will only block when the buffer is full and asynchronous cannot handle it.
for example:
Unbuffered :
package main
import (
"fmt"
"time"
)
var ch chan int
func a() {
time.Sleep(3 * time.Second)
a := 5
ch <- a
fmt.Println("out of a")
}
func b() {
time.Sleep(1 * time.Second)
}
func main() {
ch = make(chan int) // 无缓冲管道
go a()
go b()
time.Sleep(20 * time.Second)
fmt.Println("out of main")
}
output:
out of main
buffered :
package main
import (
"fmt"
"time"
)
var ch chan int
func a() {
time.Sleep(3 * time.Second)
a := 5
ch <- a
fmt.Println("out of a")
}
func b() {
time.Sleep(1 * time.Second)
}
func main() {
ch = make(chan int, 1) // 有缓冲管道
go a()
go b()
time.Sleep(20 * time.Second)
fmt.Println("out of main")
}
output:
out of a
out of main
interface
package main
import "fmt"
// Shape 是接口
type Shape interface {
Area() float64
Perimeter() float64
}
type Rect struct {
height float64
weight float64
}
func (p *Rect) Area() float64 {
return p.height * p.weight
}
func (p *Rect) Perimeter() float64 {
return 2 * (p.height + p.weight)
}
func main() {
var s Shape = &Rect{height: 10, weight: 8}
fmt.Println(s.Area())
fmt.Println(s.Perimeter())
}
In the code, Shape is an interface that declares two methods: Area and Perimeter. We define a specific structure Rect to implement this interface. It can be seen that with the basic Shape interface, one can point to a Rect object and call its method.
Golang only needs to implement all the methods of an interface, then the type is implemented. Therefore, the inheritance relationship of Golang is non-intrusive , which is also the feature and advantage of Golang.
webserver
Write it naked with http:
package main
import (
"log"
"net/http"
)
func SayHello(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello")) // 以字符串"hello"作为返回包
}
func main() {
http.HandleFunc("/say_hello", SayHello)
err := http.ListenAndServe(":8080", nil) // 开启一个http服务
if err != nil {
log.Print("ListenAndServe: ", err)
return
}
}
Run it, and then you can visit: http://localhost:8080/say_hello
Write at the end:
The above is the content of this article, thank you for reading.
If you feel that you have gained something, you can give the blogger a like.
If there are omissions or mistakes in the content of the article, please private message the blogger or point it out in the comment area~