1、第一个go程序:helloword
Golang标准库文档
安装go开发环境
安装 goland 百度云盘链接:
安装 go 百度云盘链接:
提取码:1234
helloworld源码:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
2、变量的定义
2.1 定义常量
var a int // 默认为 0
var b string = "hello"
c := 3.14 // 第一次定义变量可以 用 :号
x, y := 3,"world"
2.2 定义数组
package main
import "fmt"
func main() {
var a1 []float64 = []float64{3.14, 2.20, 3.14} // 定义一维数组
b1 := []int{0, 1, 2, 3} // 定义一维数组
arr := [3][2]int{ // 定义二维数组
{0,0},
{1,4},
{2,9},
}
fmt.Println(a1) // 打印
fmt.Println(b1)
fmt.Println(arr)
}
2.3 定义map
school := make(map[string]string) // 定义 map
school["stu1"] = "xiaoming" // 赋值
school["stu2"] = "xiaohong"
school["stu3"] = "xiaolan"
for k,v := range school{ // 遍历 map
fmt.Println("k==",k,"v==",v)
}
3、数组的切片,追加
b1 := []int{0, 1, 2, 3} // 定义一维数组
sli := b1[1:3] //截取元素 1,2
sli2 := b1[:3] //从头开始截取 截取元素 0,1,2
sli = append(sli,100) // 追加元素 100
4、封装,继承,多态
4.1 函数的封装
package main
import (
"fmt"
"math"
)
type Point struct{ // 结构体的定义
x,y float64
}
// 求两点之间距离的一般方法
func getDis(p1, p2 Point) float64{
return math.Hypot(p2.x-p1.x, p2.y-p1.y)
}
// 函数的封装
func (this *Point)getDis2(p Point) float64{
return math.Hypot(p.x-this.x, p.y-this.y)
}
func main() {
p1 := Point{0.0, 0.0}
p2 := Point{3.0, 4.0}
fmt.Println(getDis(p1, p2))
fmt.Println(p1.getDis2(p2))
}
4.2 继承
package main
import "fmt"
type Human struct {
name string
age int
sex string
}
type SuperMan struct {
Human // 继承 Human类
name string
level int
}
// 函数的封装
func (p *Human) setName(xn string) {
p.name = xn
}
func (p *Human) setAge(xa string) {
p.name = xa
}
func (p *Human) setsex(xb string) {
p.name = xb
}
func (p *SuperMan) setlevel(l int) {
p.level = l
}
func main() {
h1 := Human{"aobama",56,"man"}
var s1 SuperMan
s1.Human = h1
s1.name = "lubenwei"
s1.setlevel(5)
fmt.Println(h1)
fmt.Println(s1)
}
4.3 多态
多态就是同一个接口,使用不同的实例而执行不同操作
package main
import "fmt"
type Coder interface { // 定义接口
sleeping()
coding()
}
type Pythoner struct {
name string
}
type BlockChainer struct {
name string
}
func (x *Pythoner) sleeping(){
fmt.Println("python coder", x.name,"is sleeping")
}
func (x *BlockChainer) sleeping(){
fmt.Println("blockchainer coder", x.name,"is sleeping")
}
func (x *Pythoner) coding(){
fmt.Println("python coder", x.name,"is coding")
}
func (x *BlockChainer) coding(){
fmt.Println("blockchainer coder", x.name,"is coding")
}
func school (name string, x int) Coder {
if x == 1{
return &Pythoner{name}
}else if x == 2{
return &BlockChainer{name}
}
return nil
}
func main() {
p1 := Pythoner{"xiaohong"}
p1.sleeping()
b2 := BlockChainer{"xiaolan"}
b2.coding()
x3 := school("luxiaofeng",2) //多态,输入1和2 执行不同操作
if x3 != nil{
x3.coding()
}
}
5、go的并发,同步
5.1 并发
go语言中定义了比线程还要小的单位——协程
package main
import (
"fmt"
"time"
)
func fib(x uint) uint {
if x < 2 {
return x
}
return fib(x-2) + fib(x-1)
}
func spinner(delay time.Duration){
for { // 死循环
for _,v := range `-\|/`{
fmt.Printf("\r%c", v)
time.Sleep(100 * time.Microsecond) //睡眠固定
}
}
}
func main() {
go spinner(100 * time.Millisecond) //go命令启动协程 如果程序不是
//并发运行,该程序会永久运行
const n = 45
fibN := fib(n)
fmt.Println("\n","result==", fibN)
}
5.2 同步
协程共享资源 —> 协程间需要同步
协程间的同步机制:
1、Sync
2、channel
发生阻塞的场景:
1、通道中无数据,向通道写数据,但无协程读取
2、通道中无数据,但执行读通道
package main
//本程序大致执行顺序为 @1 -> @2 -> @3-> @4 -> @5
import (
"fmt"
"runtime"
"time"
)
func sendNum(c chan int){
fmt.Println("begin with") //@1
c <- 7 // 通道中无数据,向通道写数据, @2
// 但无协程读取,会发生阻塞
fmt.Println("end with") // @5
}
func main() {
c := make(chan int) // 创建通道 @1
go sendNum(c) // 启动协程 @1
time.Sleep(time.Second * 2) // 睡眠2s , 先让 sendNum 执行 @1
num := <- c // 读通道 @3
fmt.Println("num====",num) // @4
runtime.Gosched() // @5
}
6、go的json处理
6.1 结构体转换成json
package main
import (
"encoding/json"
"fmt"
"log"
)
// 首字母大写很关键
type Person struct { // 结构体首字母大写可以让其他文件引用
Name string // 结构体内字段字母大写可以被转换或者引用
Age int
Sex string
Like []string
Real bool
}
func main() {
p1 := Person{"duanzong",50,"man",[]string {"drink","man"},false}
fmt.Println(p1)
data, err := json.Marshal(p1)
if err != nil{
log.Fatal("fail to ")
}
fmt.Println(string(data))
}