go学习总结点东东

defer  panic  recover

json序列化
monster := Monster{"a",2,"d"}
jsonStr,err := json.Marshal(monster)
if err != nil{
   fmt.Println("json ", err)
}
fmt.Println(string(jsonStr))

data,err := json.Marshal(&monster)
fmt.Println(string(data))


json反序列化
var monster Monster
err := json.Unmarshal([]byte(str),&monster)


%c = 字符 该值对应的unicode码值
%d = 整数 表示为十进制
%v = 值的默认格式表示
%f = 有小数部分但无指数部分,如123.456
%t = 单词true或false

基本数据转string
第一
fmt.Sprintf("%参数",表达式)
第二
var num3 int = 99
str = strconv.FormatInt(int64(num3),10)
fmt.Printf("str type %T str=%q\n",str,str)

var num4 float64 = 23.857
str = strconv.FormatFloat(num4,'f',10,64) 

var b2  boot = true
str=strconv.FormatBool(b2)

var num5 int64 = 4567
str = strconv.Itoa(int(num5))

string转基本数据
var str string = "true"
var b bool
b,_ = strconv.ParseBool(str)

var str2 string = "1234567890"
var n1 int64
n1,_ = strconv.ParseInt(str,10,64)
fmt.Print("n1 type %T n1=%v",n1,n1)

var str3 string = "123.456"
var f1 float64
f1,_ = strconv.ParseFloat(str3,64)

时间函数
获取当前时间
now := time.Now()
fmt.Printf("now=%v now type=%T",now,now)
//2.通过now可以获取到年月日,时分秒
fmt.Printf("年=%v\n",now.Year())
fmt.Printf("月=%v\n",now.Month()) fmt.Printf("月=%v\n",int(now.Month()))
fmt.Printf("日=%v\n",now.Day())
fmt.Printf("时=%v\n",now.Hour())
fmt.Printf("分=%v\n",now.Minute())
fmt.Printf("秒=%v\n",now.Second())

格式化日期和时间
1、
fmt.Prinf("当前年月日 %d-%d-%d %d:%d:%d \n",now.Year(),now.Month(),now.Day(),now.Hour(),now.Minute(),now.Second())
dateStr := fmt.SPrintf("当前年月日 %d-%d-%d %d:%d:%d \n",now.Year(),now.Month(),now.Day(),now.Hour(),now.Minute(),now.Second())
fmt.Printf("datestr=%v",dateStr)

2、
now := time.Now()
fmt.Printf(now.Format("2006/01/02 15:04:05"))
fmt.Printf(now.Format("2006/01/02"))
fmt.Printf(now.Format("15:04:05"))

Unix和UnixNano的使用
now := time.Now()
fmt.Printf("Unix时间=%v   UnixNano时间=%v \n",now.Unix(),now.UnixNano())
===================================================
===================================================
链表
//给链表插入一个结点
//编写第一种插入方法,在单链表的最后加入.[简单]
func InsertHeroNode(head *HeroNode, newHeroNode *HeroNode) {
    //思路
    //1. 先找到该链表的最后这个结点
    //2. 创建一个辅助结点[跑龙套, 帮忙]
    temp := head
    for {
        if temp.next == nil { //表示找到最后
            break
        }
        temp = temp.next // 让temp不断的指向下一个结点
    }

    //3. 将newHeroNode加入到链表的最后
    temp.next = newHeroNode
}

//给链表插入一个结点
//编写第2种插入方法,根据no 的编号从小到大插入..【实用】
func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode) {
    //思路
    //1. 找到适当的结点
    //2. 创建一个辅助结点[跑龙套, 帮忙]
    temp := head
    flag := true
    //让插入的结点的no,和temp的下一个结点的no比较
    for {
        if temp.next == nil {//说明到链表的最后
            break
        } else if temp.next.no >= newHeroNode.no {
            //说明newHeroNode 就应该插入到temp后面
            break 
        } else if temp.next.no == newHeroNode.no {
            //说明我们额链表中已经有这个no,就不然插入.
            flag = false
            break
        }
        temp = temp.next
    }

    if !flag {
        fmt.Println("对不起,已经存在no=", newHeroNode.no)
        return
    } else {
        newHeroNode.next = temp.next
        temp.next = newHeroNode
    }


}
//删除一个结点
func DelHerNode(head *HeroNode, id int) {
    temp := head
    flag := false
    //找到要删除结点的no,和temp的下一个结点的no比较
    for {
        if temp.next == nil {//说明到链表的最后
            break
        } else if temp.next.no == id {
            //说明我们找到了.
            flag = true
            break
        }
        temp = temp.next
    }
    if flag {//找到, 删除

        temp.next = temp.next.next
    } else {
        fmt.Println("sorry, 要删除的id不存在")
    }
}

//显示链表的所有结点信息
func ListHeroNode(head *HeroNode) {

    //1. 创建一个辅助结点[跑龙套, 帮忙]
    temp := head

    // 先判断该链表是不是一个空的链表
    if temp.next == nil {
        fmt.Println("空空如也。。。。")
        return 
    }
    //2. 遍历这个链表
    for {
        fmt.Printf("[%d , %s , %s]==>", temp.next.no, 
            temp.next.name, temp.next.nickname)
        //判断是否链表后
        temp = temp.next
        if temp.next == nil {
            break
        }
    }
}
func main() {

    //1. 先创建一个头结点, 
    head := &HeroNode{}

    //2. 创建一个新的HeroNode
    hero1 := &HeroNode{
        no : 1,
        name : "宋江",
        nickname : "及时雨",
    }

    hero2 := &HeroNode{
        no : 2,
        name : "卢俊义",
        nickname : "玉麒麟",
    }

    hero3 := &HeroNode{
        no : 3,
        name : "林冲",
        nickname : "豹子头",
    }

    // hero4 := &HeroNode{
    //     no : 3,
    //     name : "吴用",
    //     nickname : "智多星",
    // }

    //3. 加入
    InsertHeroNode2(head, hero3)
    InsertHeroNode2(head, hero1)
    InsertHeroNode2(head, hero2)
    
    // 4. 显示
    ListHeroNode(head)

    // 5 删除
    fmt.Println()
    DelHerNode(head, 1)
    DelHerNode(head, 3)
    ListHeroNode(head)
}
===================================================
===================================================
//对列
//使用一个结构体管理环形队列
type CircleQueue struct {
    maxSize int // 4
    array [5]int // 数组
    head  int //指向队列队首 0
    tail int  //指向队尾 0
}
//如队列 AddQueue(push)  GetQueue(pop)
//入队列
func (this *CircleQueue) Push(val int)  (err error) {
    if this.IsFull() {
        return errors.New("queue full")
    }
    //分析出this.tail 在队列尾部,但是包含最后的元素
    this.array[this.tail] = val //把值给尾部
    this.tail = (this.tail + 1) % this.maxSize
    return 
}
//出队列
func (this *CircleQueue) Pop() (val int, err error) {
    if this.IsEmpty() {
        return 0, errors.New("queue empty")
    }
    //取出,head 是指向队首,并且含队首元素
    val = this.array[this.head]
    this.head = (this.head + 1) % this.maxSize
    return 
}
//显示队列
func (this *CircleQueue) ListQueue() {
    fmt.Println("环形队列情况如下:")
    //取出当前队列有多少个元素
    size := this.Size()
    if size == 0 {
        fmt.Println("队列为空")
    }

    //设计一个辅助的变量,指向head
    tempHead := this.head
    for i := 0; i < size; i++ {
        fmt.Printf("arr[%d]=%d\t", tempHead, this.array[tempHead])
        tempHead = (tempHead + 1) % this.maxSize
    }
    fmt.Println()
}
//判断环形队列为满
func (this *CircleQueue) IsFull() bool {
    return (this.tail + 1) % this.maxSize == this.head 
}
//判断环形队列是空
func (this *CircleQueue) IsEmpty() bool {
    return this.tail == this.head 
}
//取出环形队列有多少个元素
func (this *CircleQueue) Size() int {
    //这是一个关键的算法.
    return (this.tail + this.maxSize - this.head ) % this.maxSize
}
func main() {

    //初始化一个环形队列
    queue := &CircleQueue{
        maxSize : 5,
        head : 0,
        tail : 0,
    }
    var key string 
    var val int
    for {
        fmt.Println("1. 输入add 表示添加数据到队列")
        fmt.Println("2. 输入get 表示从队列获取数据")
        fmt.Println("3. 输入show 表示显示队列")
        fmt.Println("4. 输入exit 表示显示队列")

        fmt.Scanln(&key)
        switch key {
            case "add":
                fmt.Println("输入你要入队列数")
                fmt.Scanln(&val)
                err := queue.Push(val)
                if err != nil {
                    fmt.Println(err.Error())
                } else {

                    fmt.Println("加入队列ok")
                }
            case "get":
                val, err := queue.Pop()
                if err != nil {
                    fmt.Println(err.Error())
                } else {
                    fmt.Println("从队列中取出了一个数=", val)
                }
            case "show":
                queue.ListQueue()
            case "exit":
                os.Exit(0)
        }
    }
}

===================================================
===================================================
//栈
//使用数组来模拟一个栈的使用。
type Stack struct{
   MaxTop int  //表示我们栈最大可以存放数个数
   Top int     //表示栈顶,因为栈顶固定,因此我们直接使用Top
   arr [5]int  //数组模拟栈
}
//入栈
func (this *Stack) Push(val int) (err error){
   //先判断栈是否满了
   if this.Top == this.MaxTop -1 {
        fmt.Println("stack full")
        return errors.New("stack full")
   }
   this.Top++
    //放入数据
   this.arr[this.Top] = val

//出栈
func (this *Stack) Pop() (val int,err error){
     //判断栈是否空
     if this.Top == -1 {
        fmt.Println("stack mepty!")
        return 0,errors.New("stack empty")
     }
     //先取值,再 this.Top--
     var = this.arr[this.Top]
     this.Top--
     return val,nil
    
}
//遍历栈,从栈顶开始遍历
func (this *Stack) List(){
   //判断栈是否空
   if this.Top == -1{
       fmt.Println("stack empty")
       return
   }
   //curTop := this.Top
   for i := this.Top; i>=0; i-- {
       fmt.Println("arr[%d]=%d\n",i,this.arr[i])
   }
}
func main(){
   stack := &Stack{
      MaxTop : 5,
      Top : -1,
   }
   //入栈
   stack.Push(1)
   stack.Push(2)
   stack.Push(3)
   stack.Push(4)
   stack.Push(5)
   //显示
   stack.List()

   val,_ := stack.Pop()
   fmt.Println("出栈",val)
   stack.List()
}
===================================================
===================================================
二叉树
type Hero struct{
   No int
   Name string
   Left *Hero
   Right *Hero
}
//前序
func PreOrder(node *Hero){
   if node != nil {
      fmt.Printf("no=%d name=%s\n",node.No,node.Name)
      PreOrder(node.Left)
      PreOrder(node.Right)
   }
}
//中序
func InfixOrder(node *Hero){
   if node != nil {
      InfixOrder(node.Left)
      fmt.Printf("no=%d name=%s\n",node.No,node.Name)
      InfixOrder(node.Right)
   }
}
//后序
func PostOrder(node *Hero){
   if node != nil {
      PostOrder(node.Left)
      PostOrder(node.Right)
      fmt.Printf("no=%d name=%s\n",node.No,node.Name)
   }
}
func main(){
   root := &Hero{
       No : 1,
       Name : "aa",
   }
   left1 := &Hero{
       No : 2,
       Name : "bb",
   }
   node10 := &Hero{
       No : 10,
       Name : "tom"
   }
   node12 := &Hero{
       No : 12,
       Name : "tomA
   }
   left1.Left = node10
   left1.Right = node12
   
   right1 := &hero{
       No : 3,
       Name : "cc",
   }
   root.Left = left1
   root.Right = right1
   right2 := &hero{
       No : 4,
       Name : "dd",
   }
   right1.Right = right2

   PreOrder(root)
}
===================================================
===================================================
//闭包
func AddUpper() func(int) int {
   var n int = 10
   return func(x int) int {
      n = n + x
      return n
   }
}
func main(){
   f := AddUpper()
   fmt.Println(f(1)) //11
   fmt.Println(f(2)) //13
   fmt.Println(f(3)) //16
}
===================================================
===================================================
//错误处理
func test(){
   //使用defer + recover 来捕获和处理异常
   defer func(){
       err := recover() // recover() 捕获异常
       if err != nil{
            fmt.Println("err=",err)     
       }
   }()
   num1 := 10
   num2 := 20
   res := num1 /num2
   fmt.println("res=",res)
}
func main(){
   test()
   for{
       fmt.Println("")
       time.Sleep(time.Second)
   }
}
===================================================
===================================================
//斐波那契
func fbn(n int) ([]uint64){
   fbnSlice := make([]uint64,n)
   fbnSlice[0]=1
   fbnSlice[1]=1
   for i := 2; i        fbnSlice[i] = fbnSlice[i - 1] + fbnSlice[i-2]
   }
   return fbnSlice
}
func main(){
   fnbSlice := fbn(10)
   fmt.Println("fnbSlice",fnbSlice)
}
===================================================
===================================================
//冒泡排序
func BubbleSort(arr *[5]int) {
       fmt.Println("排序前arr=",(*arr))
       temp := 0
       for i := 0; i< len(*arr)-1; i++ {
           for j :=0; j                  if (*arr)[j] > (*arr)[j + 1] {
                        temp = (*arr)[j]
                        (*arr)[j] = (*arr)[j + 1]
                        (*arr)[j + 1] = temp
                 }
           }
       }
   fmt.Println("排序后arr=",(*arr))
}
===================================================
===================================================
//三种排序  选择排序 8万数据 用时:12秒  
//          插入排序 8万数据 用时:4秒 
//          快速排序 8万数据 用时:0秒 
//选择排序
func selectSort(arr *[5]int){
     for j:=0;j          max := arr[j]
         maxIndex := j
         for i :=j+1;i              if max < arr[i] {
                 max = arr[i]
                 maxIndex = i
             }
         }
         //交换
         if maxIndex != j{
              arr[j],arr[maxIndex] = arr[maxIndex],arr[j]
         }
         fmt.Printf("第%d次 %v\n ",j+1,*arr)
     }
}
func main(){
    arr := [5]int{10,34,19,100,80}
    fmt.Println(arr)
    selectSort(&arr)
    fmt.Println("main")
    fmt.Println(arr)
}
===================================================
===================================================
//插入排序
func InsertSort(arr *[5]int){
     for i := 1; i < len(arr);i++{
         insertVal :=arr[i]
         insertIndex := i - 1 //下标
         //从大到小
         for insertIndex >= 0 && arr[insertIndex] < insertVal {
             arr[insertIndex + 1] = arr[insertIndex] //数据后移
             insertIndex --
         } 
         //插入
         if insertIndex + 1 != i {
              arr[insertIndex + 1] =insertVal             
         }
         fmt.Println("第%d次插入后",*arr)
     } 
}
func main(){
      arr := [5]int{23,0,12,56,34}
      fmt.Println("原始数组=",arr)
      InsertSort($arr)
      fmt.Println("main")
      fmt.Println(arr)
}
===================================================
===================================================
//快速排序
//left 表示 数组左边的下标
//right 表示 数组右边的下标
//array 表示要排序的数组
func QuickSort(left int,right int,array *[6]int){
     l := left
     r := right
     //pivot 是中轴,支点开发左右分
     pivot := array[(left + right) / 2]
     temp := 0
     //for 循环的目标是将比较 pivot 小的数放到了左边  比 pivot 大的放到右边
     for ;l < r;{
         for ; array[l] < pivot; {
              l++
         }
         for ; array[r] < pivot; {
              r--
         }
         if l >= r {
             break
         }
         temp = array[l]
         array[l] = array[r]
         array[r] = temp
         if array[l] == pivot {
             r--
         }
         if array[r] == pivot {
             l++
         }
     }
     if l == r {
        l++
        r--
     }
     if left < r {
         QuickSort(left,r,array)
     }
     if right > l {
         QuickSort(l,right,array)
     }
}
func main() {
    arr := [6]int{-9,78,0,23,-576,70}
    QuickSort(0,len(arr)-1,&arr)
}
===================================================
===================================================
//顺序查找
names := [4]string{"a","b","c","d","e","f"}
var heroName = ""
fmt.Scanln(&heroName)

for i := 0;i     if heroName ==names[i] {
          fmt.Printf("找到",heroName,i)
          break
    } else if i==(len(names)-1) {
          fmt.Printf("没找到",heroName)
    }
}
===================================================
===================================================
//二分
func BinaryFind(arr *[6]int,leftindex int,rightIndex int, findVal int){
   if leftindex > rightIndex {
        fmt.Println("没找到")
        return
   }
   middle = (leftindex + rightIndex)/2
   if (*arr)[middle] > findVal {
       BinaryFind(arr,leftIndex,middle -1,findVal)
   }else if (*arr)[middle] < findVal {
       BinaryFind(arr,middle+1,rightIndex,findVal)
   }else{
       fmt.Printf("找到",middle)
   }
}
func main(){
   arr := [6]int{1,4,6,9,5,33,22,75}
   BinaryFind(&arr,0,len(arr)-1,33)
}
===================================================
===================================================
//map排序
map1 := make(map[int]int,10)
map1[10] = 100
map1[1]=13
map1[4]=56

var keys []int
for k,_:= range map1 {
   keys = append(keys,k)
}
sort.Ints(keys)

for _,k := range keys {
    fmt.Printf("map1[%v]=%v \n",k,map1[k])
}
===================================================
===================================================
//协程
//协程特点
1、有独产的栈空间
2、共享程序堆空间
3、调度由用户控制
4、协程是轻量级的线程
num := runtime.NumCPU() //CPU数
runtime.GOMAXPROCS(num)//num-1 cpu运行go程序
1)全局变量加锁
2)chan

//加锁
var lock sync.Mutex //加互斥锁

time.Sleep(10 * time.Second)
lock.Lock()
for k,v := range m{
   fmt.Printf('%d != %v\n',k,v)
}
lock.Unlock()
===================================================
===================================================
//协程与管道
//write Data
func writeData(intChan chan int){
    for i := 1;i <= 50; i++ {
         //放入数据
         intChan<- i
    }
    close(intChan)//关闭
}
//read data
func readData(intChan chan int,exitChan chan bool){
    for {
       v,ok := <-intChan
       if !ok {
          break
       }
       fmt.Printf("readData 读到数据=%v\n",v)
    }
    //readData 读取完数据后,任务完成
    exitChan<- true
    close(exitChan)
}

func main(){
   //创那建两个管道
   intChan := make(chan int,50)
   exitChan := make(chan bool,1)

   go writeData(intChan)
   go readData(intChan,exitChan)

   for {
      _,ok := <-exitChan
      if !ok {
         break
      }
   }
   
}
===================================================
===================================================
//使用select可以解决从管道取数据的阻塞问题
func main(){
    //使用select可以解决从管道取数据的阻塞问题
    // 1.定义一个管道 10个数据
    intChan := make(chan int,10)
    for i := 0; i<10;i++ {
        intChan <- i
    }
    // 2.定义一个管道 5个数据string
    stringChan := make(chan string, 5)
    for i := 0; i < 5; i++ {
        stringChan <- "hello" + fmt.Sprintf("%d",i)
    }
    label :
    for {
        //注意:这里,如果intChan一直没有关闭,不会一直阻塞而deadlock
        //会自动到下一个case匹配
       select {
           case v := <-intChan : 
                fmt.Printf("从intChan读取的数据%d\n",v)
           case v := <-stringChan :
                fmt.Printf("从stringChan读取的数据%s\n",v)
           default:
                fmt.Printf("都取不到了取的数据\n")
           //return  
           break label
       }
    }
}
===================================================
===================================================
var intArr3 [5]int
//为了每次生成的随机数不一样,我们需要给一个seed值
rand.Seed(time.Now().UnixNano())
for i := 0; i < len(intArr3); i++ {
    intArr3[i] = rand.Intn(100) //0<=n<100
}

fmt.Println("交换前=",intArr3)
//反转打印,交换的次数是 len / 2,
//倒数第一个和第一个元素交换,倒数第二个和第二个元素交换
temp := 0
for i := 0; i < len(intArr3) / 2; i++ {
     temp = intArr3[len(intArr3) - 1 - i]
     intArr3[len(intArr3) - 1 - i] = intArr3[i]
     intArr3[i] = temp
}
fmt.Println('交换后=',intArr3)


go build gocode\ch06\fundeme01\main  //会生成 main.exe
go build -o bin\my.exe gocode\ch06\fundeme01\main  //会生成 my.exe
在生成的全局订单ID头部添加了分库与分表的信息,这样只根据订单ID,我们也能快速的查询到对应的订单信息。

你可能感兴趣的:(go)