Go语言的基础语法
1.Go語言
1.命令
1.1 查看版本號
go version1.2 查看安裝信息
go env2.資料
2.1 官方文檔
https://studygolang.com/pkgdoc
2.2 md 語法
https://www.appinn.com/markdown/
2.3 go環境的安裝
官網安裝包下載地址為:https://golang.org/dl/
如果打不開可以使用這個地址:https://golang.google.cn/dl/
2.4注意事項
1.把liteIDEA放到go安裝的根目錄下
2.ctrl+F7 編譯運行
3.helloWorld函數
package mainimport "fmt"func main() {fmt.Println("hello go") }2.語法
2.1
2.1聲明變量
var a int fmt.Println("a = ",a)2.1.1 聲明變量特殊語法(常用)
var a int = 40a = 30fmt.Println("a = ", a) //c :=30 == var a int = 40 常用c := 30fmt.Printf("param type is %T\n", c)2.1.2 兩個變量互換位置
i, j := 10, 20i, j = j, ifmt.Printf("i= %d,j = %d\n", i, j)2.1.3 匿名函數互換位置
//匿名函數 _函數配合函數 返回值使用q, w := 10, 20q, _ = w, qfmt.Printf("q= %d\n", q)2.1.4 函數調用
//go函數可以返回多個值 func test() (a, b, c int) {return 1, 2, 3 } //調用函數var c, d, e intc, d, e = test() //return 1,2,32.1.5 匿名函數調用
//匿名函數_, d, _ = test() //return 1,2,3fmt.Printf("c =%d , d =%d ,e =%d\n", c, d, e)2.1.6 常量關鍵字 const
const a int = 10fmt.Printf("a =%d", a)const b = 11.22.1.7 枚舉iota
2.1.7.1 iota常量自動生成器,每個一行,自動累加1
2.1.7.2 iota給常量賦值使用
//1.iota常量自動生成器,每個一行,自動累加1//2.iota給常量賦值使用const (a = iota //0b = iota //1c = iota //2)fmt.Printf("a =%d,b =%d ,c =%d", a, b, c)2.1.7.3 iota遇到const,重置為0
//3.iota遇到const,重置為0const d = iota //0fmt.Printf("d =%d\n", d)2.1.8 字符串
package mainimport "fmt"func main() {var str1 stringstr1 = "abc"fmt.Println("str1 = ", str1)//自動推導類型str2 := "make"fmt.Println("str2 =", str2)//內建函數 長度fmt.Println("len(str2) =", len(str2))}2.1.9 復數
var t complex128 //聲明t = 2.1 + 3.14ifmt.Println("t =", t)//自動推導類型t2 := 3.3 + 4.4ifmt.Printf("t2 type is %T\n", t2)//通過內建函數,取實部和虛部fmt.Println("real t2 = ", real(t2))2.1.10 類型別名
type bigint int64var a biginttype (long int64char byte)var b long = 11var ch char = 'a'fmt.Printf("b = %d, ch = %c\n", b, ch)2.1.11 if類型
//if類型 初始化變量 當a=10時,跳轉到括號if a := 10; a == 10 {fmt.Println("a =", 10)}2.1.11 range類型(迭代)
for i := 0; i < len(str); i++ {fmt.Printf("str[%d] = %c\n", i, str[i])}fmt.Println("------")//i是下標for i, data := range str {fmt.Printf("str[%d]=%c\n", i, data)}fmt.Println("------")for i := range str {fmt.Printf("str[%d]=%c\n", i, str[i])}for i, _ := range str {fmt.Printf("str[%d]=%c\n", i, str[i])}2.1.12 goto類型
//Endfmt.Println("1111")goto Endfmt.Println("222") End:fmt.Println("333")##2.2
2.2.1函數定義(無返回值)
func Myfunc() {a := 111fmt.Println("無參= ", a)} func Myfunc1(a int) {fmt.Println("有參= ", a)} func Myfunc2(a int, b int) {fmt.Printf("a = %d,b=%d\n", a, b) } func Myfunc3(a string, b int, c float32) {fmt.Printf("a = %d,b=%d,c = %d \n,", a, b, c) }func main() {Myfunc()Myfunc1(222)Myfunc2(333, 444)Myfunc3("555", 666, 777.1) }2.2.2函數定義(有返回值)
//有返回值 func Myfunc2(a int, b int) (max int, mix int) {max = amix = breturn //有返回值的函數,必須通過return返回 }func main() {var a int_, a = Myfunc2(333, 444)fmt.Println("a=", a)}2.2.3函數類型
func addF(a int, b int) int {return a + b } func minF(a int, b int) int {return a - b }//定義函數類型 //FuncType是一個函數類型 type FuncType func(int, int) int //沒有函數名字 沒有{}func main() {var result intvar TestF = FuncTypeTestF = minFresult = TestF(20, 10)fmt.Println("a=", result) }2.2.4函數類型(回調函數,多態)
func add(a int, b int) int {return a + b }// func addF(a int, b int, dtest FuncType) (result int) {result = dtest(a, b)return }//定義函數類型 //FuncType是一個函數類型 type FuncType func(int, int) int //沒有函數名字 沒有{}func main() {a := addF(1, 1, add)fmt.Println("a =", a) }2.2.5匿名函數+閉包
func main() {a := 10b := 20//1.定義匿名函數f1 := func() {fmt.Println("a = ", a)fmt.Println("b = ", b)}//2.匿名函數類型type FuncType1 func()var f2 FuncType1f2 = f1f2()fmt.Println("a =", a)//3.定義匿名函數func() {fmt.Println("a = ", a)fmt.Println("b = ", b)}()//()表示調用此函數//4 有參匿名函數f4 := func(a,b int) {fmt.Println("a = ", a)fmt.Println("b = ", b)}f4(4,5)//5.無名匿名帶參數func(a,b int) {fmt.Println("a = ", a)fmt.Println("b = ", b)}(5,6)//()表示調用此函數//6.匿名函數有參有返回值x,y = func(i,j int)(max,min int){max = imin = jreturn }(10,20)}2.2.5閉包 匿名函數 變量
func test2() func() int {var x int //沒有初始化,值為0return func() int {x++return x * x} }func main() {f := test2()//閉包-不關心變量和常量是否已經超出作用于//只要閉包還在使用它,這些變量就還存在fmt.Println(f()) //1fmt.Println(f()) //4fmt.Println(f()) //9 }2.2.6 defer的使用
//defer延遲調用 main函數結束前調用defer fmt.Println("bbb")fmt.Println("aaaaa") //有多個defer語句,則是 先進后出 哪怕函數出錯 依舊會執行 defer fmt.Println("111") defer fmt.Println("222") defer fmt.Println("333")//匿名函數表示,把變量賦值過去 但是沒有調用defer func(a,b int){fmt.Printf("a = %d ,b = %c\n",a,b)}(10,20)2.2.7 獲取命令行參數
func main() {//要先go build 成 exelist := os.Argsn := len(list)fmt.Println("n =", n)for i := 0; i < n; i++ {fmt.Printf("list[%d] = %s\n", i, list[i])}for i, data := range list {fmt.Printf("list[%d] = %s\n", i, data)} }2.2.8 變量
1.不同作用域可以有同名變量 2.使用變量的原則,就近原則2.2.9 導入導出包
//給包起別名 import io "fmt" io.Println("起別名") //忽略包 import _ "fmt"2.2.10 init函數
先執行 init函數 在執行main函數
2.3 復合類型
2.3.1聲明變量 指針類型
//變量兩含義 1內存 2地址var num int = 10fmt.Printf("a = %d\n ", num)fmt.Printf("a = %v\n ", &num)//保存變量的地址 需要指針類型var p *intp = &numfmt.Printf("p = %v\n ,&a = %v\n ", p, &num)2.3.2默認值 nil new函數
var p *intp = nilfmt.Println("平= ", p)//p := new(int)*p = 7772.3.3數組定義賦值
func main() {var arr [20]intfor i := 0; i < len(arr); i++ {arr[i] = i + 1fmt.Printf("arr[%d] = %d\n", i, arr[i])}//數組定義 置值,其他值為0arr1 := [5]int{1, 2, 3}//指定位置賦值arr2 := [5]int{2: 1, 3: 4}fmt.Println(arr2)}2.3.4 隨機數
import "fmt" import "time" import "math/rand" func main() {//設置隨機數種子rand.Seed(time.Now().UnixNano()) //當前的系統執行時間for i := 0; i < 5; i++ {fmt.Println("rand =", rand.Intn(100))}}2.3.5數組指針
import "fmt" import "time" import "math/rand" //數組指針 //*p 代表指針所指向的內存,就是實參 func modify(p *[5]int) {//p[0] = 66(*p)[0] = 666 }2.3.6切片spilt
func main() {a := []int{1, 2, 3, 54, 5, 7, 89, 6}//[low:high:max]//下標起點 下標終點 (左閉右開) 容量(max-low)s := a[0:3:5]fmt.Println("s = ", s) //[1 2 3]fmt.Println("s len =", len(s)) //長度 3fmt.Println("s cap =", cap(s)) //容量 5//創建切片b := []int{}//給切片追加一個成員b=append(b,11)//不寫默認0 從0開始取3個元素.容量為 5-0s := a[:3:5]}2.3.6切片切切片
//切片切切片a := []int{1, 2, 3, 4, 5, 7, 8, 9}s1 := a[1:3] //[2,3]fmt.Println("s1 =", s1)s2 := s1[1:5] //[3,4,5,7]fmt.Println("s1 =", s2)2.3.7 copy函數
a := []int{1, 2, 3, 4, 5}b := []int{6, 7, 8, 9, 10, 11}copy(a, b)fmt.Println("a =", a) //{6, 7, 8, 9, 10}fmt.Println("b =", b) //{6, 7, 8, 9, 10,11}2.3.7 map
2.3.7.1 map的定義
func deleMap(mapV map[int]string) {delete(mapV, 1) }//創建mapvar map1 map[int]stringfmt.Println("a =", map1) //{6, 7, 8, 9, 10}//通過make創建map2 := make(map[int]string)map2[1] = "make"map2[2] = "sss"//定義初始化map3 := map[int]string{1: "a", 2: 'b'}//刪除delete(map3, 1)fmt.Println(map3)//定義函數deleMap(map3)2.3.7.2 map的循環
//定義初始化map3 := map[int]string{1: "a", 2: "b"}//循環for key, value := range map3 {fmt.Printf("%d =====>%s\n", key, value)}//判斷一個Key值是否存在//第一個返回值為key所對應的valuevalue, ok := m[1]if ok == true {fmt.Printf("m[1] =", value)} else {fmt.Printf("key不存在")}2.3.8 結構體
type Student struct {id intname stringsex byteage intaddr string }func main() {var s1 Student = Student{1, "make", 'm', 20, "背景"}fmt.Println(s1)//{1 make 109 20 背景}//指定聲明s2 := Student{name: "make", addr: "背景"}fmt.Println(s2)//{0 make 0 0 背景}//聲明指針變量s3 := &Student{name: "make", addr: "背景"}fmt.Println(s3)//&{0 make 0 0 背景}var s4 *Student = &Student{1, "make", 'm', 20, "背景"}fmt.Printf("s4 type= %T\n", s4)//s4 type= *main.Studentfmt.Println(s4)//&{1 make 109 20 背景}//先定義在賦值var stu1 Studentstu1.id = 1stu1.name = "mike"stu1.sex = '5'fmt.Println(stu1) //{1 mike 53 0 }//new申請stu2 := new(Student)stu2.id = 1stu2.name = "mike"stu2.sex = '5'fmt.Println(stu2) //&{1 mike 53 0 }}2.3.9 可見性
如果想使用別的包的函數,結構體類型,結構體成員,函數名,類型名,結構體成員變量名
首字母必須大寫,可見
如果首字母小寫,只能能在同一個包里使用
2.4 面向對象編程
2.4.1匿名組合
type Person struct {id intname stringage int }type Student struct {Person //只有類型 沒有名字,匿名字段 繼承了person的成員garde stringclass string }2.4.1.2 定義類,賦值,修改
//定義類var per1 Student = Student{Person{1, "生活", 18}, "初中", "初一"}fmt.Println("per1", per1)//自動推導類型per2 := Student{Person{1, "生活", 18}, "初中", "初一"}fmt.Printf("per2 %v\n", per2)//單獨復制per3 := Student{class: "初一"}fmt.Printf("per3 %v\n", per3)per4 := Student{Person: Person{id: 5}, class: "初一"}per4.name = "sss"per4.Person = Person{5, "aaa", 22}fmt.Printf("per4 %v\n", per4)2.4.1.3 匿名字段追加
//非結構匿名字段 type addColum string func main() {per2 := Student{Person{1, "生活", 18}, "初中", "初一", "追加字段"}fmt.Printf("per2 %v\n", per2)//per2 {{1 生活 18} 初中 初一 追加字段} }2.4.1.4 地址匿名字段追加
//非結構匿名字段 type addColum stringtype Person struct {id intname stringage int }type Student struct {*Person //只有類型 沒有名字,匿名字段 繼承了person的成員garde stringclass stringaddColum }func main() {per2 := Student{&Person{1, "生活", 18}, "初中", "初一", "追加字段"}fmt.Printf("per2 %v\n", per2)fmt.Println(per2.id, per2.name, per2.age, per2.garde, per2.class)var per3 Studentper3.Person = new(Person)per3.addColum = "append"per3.id = 5per3.name = "sss"fmt.Println(per3.id, per3.name, per3.age, per3.garde, per3.class) }2.4.2方法
2.4.2.1 定義
//面向對象,方法:給某個類型綁定一個函數 type long int//tmp叫接受者,接受者傳遞的一個參數 func (tmp long) Add02(other long) long {fmt.Println("tmp =", tmp)//1return tmp + other}func main() {//定義一個變量var test long = 1//調用方法格式 :變量名.函數r := test.Add02(3)fmt.Println("r =", r)//4}2.4.2.2 賦值,輸出
//輸出函數 func (per Person) pringInfo() {fmt.Println("per =", per) }//賦值函數 func (per Person) setInfo(a int, b string, c int) {per.id = aper.name = bper.age = cfmt.Println("per =", per) }func main() {per1 := Person{1, "小三", 20}per1.pringInfo()per1.setInfo(2, "小三的小三", 21)}2.4.2.3 值傳遞與引用傳遞
type Person struct {id intname stringage int }//賦值函數 func (per Person) setInfo(a int, b string, c int) {per.id = aper.name = bper.age = cfmt.Printf("per = %v\n", per)//per = {3 修改 22} }//引用傳遞 func (per *Person) setInfoPoint(a int, b string, c int) {per.id = aper.name = bper.age = cfmt.Printf("per = %v\n", per)//per = &{4 修改 32} }func main() {per1 := Person{1, "小三", 20}per1.setInfo(3, "修改", 22) //引用傳遞fmt.Println(per1)//{1 小三 20}per2 := Person{2, "小三的小三", 21}per2.setInfoPoint(4, "修改", 32) //值傳遞fmt.Println(per2) //{4 修改 32}}2.4.2.4 繼承傳遞
type Person struct {id intname stringage int }type Student struct {Persongarde string } //輸出函數 func (per Person) pringInfo() {fmt.Println("per =", per) }func main() {//繼承stu := Student{Person{5, "小三5", 25}, "s"}stu.pringInfo()fmt.Println(stu)}2.4.2.5 方法值
stu := Student{Person{5, "小三5", 25}, "s"}stu.pringInfo()//方法值 保存方式入口地址pFunc := stu.pringInfo //這個就是方法值,調用函數時,無需再傳遞接受者pFunc() //等價于 stu.pringInfo()2.4.2.5 方法表達式
//方法表達式f := (*PePerson).setInfoPointf(&stu) //等價于 stu.setInfoPoint()f1 := (PePerson).setInfof1(stu) //等價于 stu.setInfo()fmt.Println(stu)2.4.3接口
2.4.3.1 定義
//定義接口 type inter interface {say() }//studnt實現了say方法 func (tmp *Teacher) say() {fmt.Printf("Studnt %s\n", tmp.zz) }func main() {var i inter//只要實現 該接口,就可以給這個接口賦值s := &Teacher{"是啥"}i = si.say()//Studnt 是啥 }2.4.3.2 繼承實現
type inter interface {say() } type inter1 interface {intersay1() }//studnt實現了say方法 func (tmp *Teacher) say() {fmt.Printf("Studnt %s\n", tmp.zz) }//studnt實現了say1方法 func (tmp *Teacher) say1() {fmt.Printf("Studnt %s\n", tmp.zz) }func main() {var i inter1//只要實現 該接口,就可以給這個接口賦值s := &Teacher{"是啥"}i = si.say()i.say1() }2.4.3.3 接口轉換
var i1 inter1 //超集i1 = &Teacher{"是啥"}var i inter //子集i = i1 //可以 超集可以轉換為子集i.say()2.4.3.4 空接口
i := make([]interface{}, 3)i[0] = 1i[1] = "ss"for index, data := range i {if value, ok := data.(int); ok == true {fmt.Printf("index [%v] ,x[%d]\n", index, value)}}2.5 異常處理,字符串
2.5.1錯誤接口(error)
err1 := fmt.Errorf("%s", "no error")fmt.Println(err1)err2 := errors.New("錯誤")fmt.Println(err2)2.5.1.1錯誤接口的應用
func MyDiv(a, b int) (result int, err error) {err = nilif b == 0 {err = errors.New("B不能為0")} else {result = a / b}return}func main() {val, err := MyDiv(1, 0)if err != nil {fmt.Println(err)} else {fmt.Println(val)}}2.5.2函數程序中斷(panic)
func test() {//導致程序中斷panic("this is a panic") }2.5.3函數程序(recover)
func test1() {defer func() {//err是該函數默認返回值if err := recover(); err != nil {fmt.Println(err)}}() //()調用此函數 }2.5.4字符串函數的使用
fmt.Println(strings.Contains("abcdefg", "abc")) //truearr := []string{"abc", "hello", "arr"}fmt.Println(strings.Join(arr, "@")) //abc@hello@arrfmt.Println(strings.Index("abcdefg", "b")) //1arrStr := "abc@hello@arr"fmt.Println(strings.Split(arrStr, "@")) //[abc hello arr]2.5.5 strconv包
arr1 := make([]byte, 0, 1024)arr1 = strconv.AppendBool(arr1, true)//整數轉字符串arr2 := strconv.Itoa(6666)fmt.Println(arr2)//其他類型轉換為字符串var str stringstr = strconv.FormatBool(false)fmt.Println(str)2.6 json
2.6.1 結構體轉json
import "fmt" import "encoding/json"//首字母必須大寫 type Student struct {Id int `json:"-"` //此字段不會輸出Name string `json:"name"` //返回時返回指定字段Sub []stringIsOk bool `json:",string"` //返回字符串Price float64 }func main() {stu := Student{1, "小明", []string{"go", "java", "php"}, true, 50.00}fmt.Println(stu)//json轉義buf, err := json.Marshal(stu)if err != nil {fmt.Println(err)return}fmt.Println(buf) //[123 34 73 100 34 58 49 44 34 78 97 109 101 34 58 34 229 176 143 230 152 142 34 44 34 83 117 98 34 58 91 34 103 111 34 44 34 106 97 118 97 34 44 34 112 104 112 34 93 44 34 73 115 79 107 34 58 116 114 117 101 44 34 80 114 105 99 101 34 58 53 48 125]fmt.Println(string(buf)) }2.6.2 map轉json
map1 := make(map[string]interface{}, 4)map1["id"] = 5map1["name"] = "實時"buf, err := json.MarshalIndent(map1, "", " ")fmt.Println(string(buf))fmt.Println(err)2.6.3 json轉實體
func main() {jsonBuf := `{"id": 5,"name": "實時"}`var stu1 Studentjson.Unmarshal([]byte(jsonBuf), &stu1)fmt.Println(stu1)//{0 實時 [] false 0}}2.6.4 json轉map
func main() {jsonBuf := `{"id": 5,"name": "實時"}`map2 := make(map[string]interface{}, 4)json.Unmarshal([]byte(jsonBuf), &map2)fmt.Println(map2)//斷言 判斷類型var str stringfor key, value := range map2 {switch data := value.(type) {case string:str = datafmt.Printf("map[%s]的值類型為string", key)case []interface{}:fmt.Printf("map[%s]interface{}", key)}}}2.7 goroutine并發并行
2.7.1 demo
import "fmt" import "time"func newWork() {for {fmt.Println("this is newWork")time.Sleep(1000)} }func main() {//設置并行處理器num := runtime.GOMAXPROCS(1)fmt.Println(num)//goroutinego newWork() //新建一個協程任務for {fmt.Println("this is mainWork")time.Sleep(1000)} }2.7.2主協程退出,子協程也退出
func main() {//主協程退出了,其它子協程也要跟著退出go func() {for {fmt.Println("this is goroutine")}}()i := 0for {i++fmt.Println("this is mainFor")time.Sleep(1000)if i > 2 {break}}}2.7.3 Goschedr讓出調度資源 Goexit 終止
import "runtime" func main() {//設置并行處理器num := runtime.GOMAXPROCS(1)fmt.Println(num)//Goschedrgo func() {for j := 0; j < 2; j++ {fmt.Println("this is goroutine")runtime.Goexit() //終止所有協程}}()i := 0for {i++fmt.Println("this is mainFor")runtime.Gosched() //讓出時間片,先讓其他協議執行if i > 2 {break}}}2.7.4
2.7.4.1 Demo channel管道
//創建一個無緩存的channel var ch = make(chan int)func printWork(val string) {fmt.Println(val)fmt.Println(val)fmt.Println(val)fmt.Println(val)fmt.Println(val)}func per(sendv string) {printWork(sendv)ch <- 666 //給管道協數據,發送 }func per1(sendv string) {<-ch //從管道取數據,接收,如果管道沒有數據阻塞printWork(sendv) }func main() {go per("per1")go per("per2")for {}// per2// per2// per2// per2// per1// per1// per1 }2.7.4.2 channel 特點
func main() { var ch3 chan<- float64 //ch3是單向channel 只用于讀寫float64數據 ch := make(chan int)//雙向隱轉單向var writhCh chan<- int = ch //只能寫,不能讀var readCh <-chan int = ch //只能讀,不能寫writh <-666 //寫<-readch//讀//單向無法轉換為雙向var ch2 chan int = writhCh}2.7.4.3 channel 應用
//生產者 只能寫,不能讀 func product(out chan<- int) {for i := 0; i < 10; i++ {out <- i * i}close(out)}//消費者 只能讀,不能寫 func consumer(in <-chan int) {for num := range in {fmt.Println("consumer=", num)}}func main() {//創建一個雙向通道ch := make(chan int)//生產者go product(ch)//消費者consumer(ch)}2.7.4.4 定時器
import "time"func main() {//只執行一次timer := time.NewTimer(2 * time.Second)//重復執行timer1 :=time.NewTicker(2 * time.Second)fmt.Println(time.Now())t := <-timer.Cfmt.Println(t)timer.Reset(1 * time.Second) //重新設置timer.Stop() //定時器停止//2020-06-13 14:06:05.8875131 +0800 CST m=+0.008002001//2020-06-13 14:06:07.8881753 +0800 CST m=+2.008664201 }2.7.4.5 select用法
func main() {ch := make(chan int)quit := make(chan bool)//新開一個協程//讀數據go func() {for {select {case num := <-ch:fmt.Println("num = ", num)case <-time.After(3 * time.Second):fmt.Println("超時")quit <- true}}}() //自調用//寫數據for i := 0; i < 5; i++ {ch <- itime.Sleep(time.Second)}<-quitfmt.Println("程序結束")}2.7.5
2.7.5.1 協議通信過程
應用層 hello 傳輸層(udp tcp) 源port 目的端口 hello 網絡層(ip) 源ip 目的ip 源port 目的端口 hello 鏈路層(mac) 源mac 目的mac 源ip 目的ip 源port 目的端口 hello2.7.5.2 tcp傳輸(服務端)
//傳輸端 func main() {listener, err := net.Listen("tcp", "127.0.0.1:8000")if err != nil {fmt.Println("err = ", err)return}defer listener.Close()//阻塞等待用戶連接for {conn, _ := listener.Accept()//接受請求buf := make([]byte, 1024)n, _ := conn.Read(buf)//buf[:n] n有多少打印多少 長度是1024所以不可以打印全部fmt.Println("puf :", string(buf[:n]))conn.Close()}}2.7.5.3 tcp傳輸(客戶端)
// tcp客戶端 package mainimport ("net" )func main() {conn, _ := net.Dial("tcp", "127.0.0.1:8000")defer conn.Close()//發送數據conn.Write([]byte("are you ok?"))}2.7.6鎖
1.讀時共享,寫時獨享 寫鎖優先級比讀鎖高
2.7.6.1 互斥鎖
package mainimport ("fmt""sync""time" )var mutex sync.Mutexvar pipeline = make(chan int)func printWord(word string) {mutex.Lock()for _, value := range word {fmt.Printf("%c",value)time.Sleep(time.Microsecond*1000)}mutex.Unlock() } func main() {go person1()go person2()for {;} } func person1() {printWord("1111111111111111111")pipeline<-666 }func person2() {<-pipelineprintWord("222222222222222222") }2.7.6.2 互斥鎖(管道)
package mainimport ("fmt""time" )var pipeline = make(chan int)func printWord(word string) {for _, value := range word {fmt.Printf("%c",value)time.Sleep(time.Microsecond*1000)}}func main() {go person1()go person2()for {;} } func person1() {printWord("1111111111111111111")pipeline<-666 }func person2() {<-pipelineprintWord("222222222222222222") }2.7.6.3 讀寫鎖
package mainimport ("fmt""math/rand""sync""time" )var rwMutes sync.RWMutex //鎖只有一把 兩個屬性var value int //定義全局變量func main() {//播種隨機數種子rand.Seed(time.Now().UnixNano())for i := 0; i < 5; i++ {go readWord(i + 1)}for i := 0; i < 5; i++ {go writeWord(i + 1)}for {;}}//寫 func writeWord(idw int) {for {wnum := rand.Intn(1000)rwMutes.Lock() //以寫模式加鎖value = wnumfmt.Printf("讀 %d==> %d\n", idw, wnum)time.Sleep(time.Microsecond * 300)rwMutes.Unlock() //}}//讀 func readWord(idx int) {for {rwMutes.RLock()rnum := valuefmt.Printf("寫 %d==>%d\n", idx, rnum)rwMutes.RUnlock()time.Sleep(time.Millisecond * 300)}}2.7.6.4 讀寫鎖管道
package mainimport ("fmt""math/rand""sync""time" )var rwMutes sync.RWMutex //鎖只有一把 兩個屬性var value int //定義全局變量//寫 func writeWord(in chan<- int,idw int) {for {wnum := rand.Intn(1000)in<-wnumfmt.Printf("讀 %d==> %d\n", idw, wnum)time.Sleep(time.Microsecond * 300)}}//讀 func readWord(re <-chan int,idx int) {for {rnum := <-refmt.Printf("寫 %d==>%d\n", idx, rnum)time.Sleep(time.Millisecond * 300)}} func main() {//播種隨機數種子rand.Seed(time.Now().UnixNano())ch1 :=make(chan int)for i := 0; i < 5; i++ {go readWord(i + 1,ch1)}for i := 0; i < 5; i++ {go writeWord(i + 1,ch1)}for {;}}2.7.6.5條件變量鎖
package mainimport ("fmt""math/rand""sync""time" )var cond sync.Cond //創建全局條件變量func consumer(in <-chan int, idx int) {for{cond.L.Lock()//條件變量對應互斥鎖枷鎖for len(in) ==0 { //產品區空 等待生產cond.Wait() //掛起當前攜程,等待全局變量滿足}num:=<-infmt.Printf("%d 消費者消費數據 %d,公共區剩余%d個數據\n",idx,num,len(in))cond.L.Unlock() //生產結束,解鎖互斥鎖cond.Signal() //喚醒阻塞的 消費者time.Sleep(time.Second)//生產完休息一會,}}func producer(out chan<- int, idx int) {for{cond.L.Lock() //條件變量對應互斥鎖枷鎖//產品區滿 等待消費者消費for len(out)==3{cond.Wait() //掛起當前攜程,等待全局變量滿足}num := rand.Intn(1000)out<-numfmt.Printf("%d 生產者生產數據 %d,公共區剩余%d個數據\n",idx,num,len(out))cond.L.Unlock() //生產結束,解鎖互斥鎖cond.Signal() //喚醒阻塞的 消費者time.Sleep(time.Second)//生產完休息一會,給其他協程執行機會}} func main() {rand.Seed(time.Now().UnixNano())//設置隨機數種子quit := make(chan bool) //創建用于結束通信的channelproduct := make(chan int, 3) //產品區(公共區)使用channel模擬cond.L = new(sync.Mutex)//創建互斥鎖和條件變量for i :=0;i<1 ;i++ {go producer(product,i+1) //5個生產者}for i :=0;i<1 ;i++ {go consumer(product,i+1) //三個消費者}<-quit //主線程阻塞 不結束 }2.7.7 file
2.7.7.1 打開文件
創建文件的步驟: (1)導入“os”包,創建文件,讀寫文件的函數都在改包 (2)指定創建的文件存放路徑以及文件名。 (3)執行Create( )函數,進行文件創建 (4)關閉文件//打開文件 package main import ("fmt""os" ) func CreataFile(path string){f, err := os.Create(path)if err != nil{fmt.Println("err=",err)return}defer f.Close() //退出關流 } func main() {var filePath = "a.txt"CreataFile(filePath) }3.連接mysql
3.1 配置環境變量
3.1.1 設置環境變量 GOPATH
GOPATH D:\goCode //項目的安裝路徑3.1.2 安裝驅動
go get github.com/go-sql-driver/mysql cmd中打開 這行命令會從github同步代碼,同步到GOPATH環境變量下3.1.3 連接數據庫
import ("database/sql""fmt"_ "github.com/go-sql-driver/mysql") var db *sql.DBfunc connectionSql(){//cannot find package "github.com/go-sql-driver/mysql" in any of://idea 配置 file settinf go 配置goPathvar err errordb,err = sql.Open("mysql","root:root@tcp(127.0.0.1:3306)/sxjl?charset=utf8");//defer db.Close()if err != nil{fmt.Printf("connect mysql fail ! [%s]",err)} }3.1.4 查詢
/** 查詢sql*/ func querySql(sql string){rows, err := db.Query(sql)if err != nil{fmt.Printf(" mysql fail resion! [%s]",err)}//https://blog.csdn.net/kenkao/article/details/47857795?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.nonecase//字典類型//構造scanArgs、values兩個數組,scanArgs的每個值指向values相應值的地址columns, _ := rows.Columns()scanArgs := make([]interface{}, len(columns))values := make([]interface{}, len(columns))for i := range values {scanArgs[i] = &values[i]}for rows.Next() {//將行數據保存到record字典err = rows.Scan(scanArgs...)record := make(map[string]string)for i, col := range values {if col != nil {record[columns[i]] = string(col.([]byte))}}fmt.Println(record)}}4.安裝Beego
4.1
https://www.cnblogs.com/personblog/p/13084723.html通用
1.fmt.Sprintf (格式化輸出)
%v 按值的本來值輸出%+v 在 %v 的基礎上,對結構體字段名和值進行展開 %#v 輸出 Go 語言語法格式的值%T 輸出 Go 語言語法格式的類型和值%% 輸出 %% 本體%b 整型以二進制方式顯示%o 整型以八進制方式顯示%d 整型以十進制方式顯示%x 整型以 十六進制顯示%X 整型以十六進制、字母大寫方式顯示%U Unicode 字符%f 浮點數%p 指針,十六進制方式顯示2.make 和 new的區別
make 被用來分配引用類型的內存: (make 只能用于 slice,map,channel 三種類型,)new 被用來分配除了引用類型的所有其他類型的內存: int, string, array等3.interface{} 類型
interface{} 類型,空接口 //由于沒有 implements 關鍵字,所以所有類型都至少實現了 0 個方法,所以 所有類型都實現了空接口func PrintAll(vals []interface{}) {for _, val := range vals {fmt.Println(val)}<br> }func main() {names := []string{"stanley", "david", "oscar"}//**********必須將[]string 轉化為 []interface{}vals := make([]interface{}, len(names))for i, v := range names {vals[i] = v}PrintAll(vals) }4.參數后面的三個點
Go語言函數中有三個點...表示為可變參數,可以接受任意個數的參數。?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
4.安裝Beego
4.1
https://www.cnblogs.com/personblog/p/13084723.html通用
1.fmt.Sprintf (格式化輸出)
%v 按值的本來值輸出%+v 在 %v 的基礎上,對結構體字段名和值進行展開 %#v 輸出 Go 語言語法格式的值%T 輸出 Go 語言語法格式的類型和值%% 輸出 %% 本體%b 整型以二進制方式顯示%o 整型以八進制方式顯示%d 整型以十進制方式顯示%x 整型以 十六進制顯示%X 整型以十六進制、字母大寫方式顯示%U Unicode 字符%f 浮點數%p 指針,十六進制方式顯示2.make 和 new的區別
make 被用來分配引用類型的內存: (make 只能用于 slice,map,channel 三種類型,)new 被用來分配除了引用類型的所有其他類型的內存: int, string, array等3.interface{} 類型
interface{} 類型,空接口 //由于沒有 implements 關鍵字,所以所有類型都至少實現了 0 個方法,所以 所有類型都實現了空接口func PrintAll(vals []interface{}) {for _, val := range vals {fmt.Println(val)}<br> }func main() {names := []string{"stanley", "david", "oscar"}//**********必須將[]string 轉化為 []interface{}vals := make([]interface{}, len(names))for i, v := range names {vals[i] = v}PrintAll(vals) }4.參數后面的三個點
Go語言函數中有三個點...表示為可變參數,可以接受任意個數的參數。?
達夢支持
有任何問題請到技術社區反饋。
24小時免費服務熱線:400 991 6599
達夢技術社區:https://eco.dameng.com
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結
- 上一篇: go连接达梦数据库
- 下一篇: DMDW集群配置到DEM