go 基础

数据类型

 字符串

字符串常用系统函数

字符串循环,长度

//计算长度
func s1() {
    s := "我爱go语言"
    fmt.Println("字节长度", len(s))
    fmt.Println("...")

    len := 0
    //遍历字符串
    for i, ch := range s {
        fmt.Printf("%d:%c
", i, ch)
        len++
    }
    fmt.Printf("
字符串长度:%d", len)
    //遍历所有字节
    for i, ch := range []byte(s) {
        fmt.Printf("%d:%x
", i, ch)
    }
    //遍历所有字符
    count := 0
    for i, ch := range []rune(s) {
        fmt.Printf("%d:%c
", i, ch)
        count++
    }
    //字符长度
    fmt.Println("len=", count)
    fmt.Println("len=", utf8.RuneCountInString(s))
}
View Code

strings使用     截取,大小写等

//是否包含子串
func s2() {
    fmt.Println(strings.Contains("seafood", "foo"))
}

//判断字符串是否包含另一字符串的任一字符
func s3() {
    fmt.Println(strings.ContainsAny("second", "one"))
}

//判断字符串是否包含unicode码值
func s4() {
    fmt.Println(strings.ContainsRune("一丁丐", ''))
    fmt.Println(strings.ContainsRune("一丁丐", 19969))
    var st int = ''
    fmt.Printf("%v", st) //19969
}

//返回字符串包含另一字符串的个数
func s5() {
    fmt.Println(strings.Count("google", "o"))
}

//判断字符串s是否有前缀字符串
func s6() {
    fmt.Println(strings.HasPrefix("1000phone", "1000"))
    fmt.Println(strings.HasPrefix("1000phone", "PHONE"))
}

//判断字符串是否有后缀字符串
func s7() {
    fmt.Println(strings.HasSuffix("1000phone news", "news"))
    fmt.Println(strings.HasSuffix("1000phone news", "new"))
}

//判断字符串中另一字符串首次出现的位置
func s8() {
    fmt.Println(strings.Index("hello world", "o")) //4
}
func s9() {
    fmt.Println(strings.IndexAny("abcABCDF", "教育基地A")) //3
}

//返回字符串中字符首次出现的位置
func s10() {
    fmt.Println(strings.IndexByte("123abc", 'a'))
}

//判断字符串是否包含unicode值
func s11() {
    fmt.Println(strings.IndexRune("abcABC", 'C'))
    fmt.Println(strings.IndexRune("abcABC", 'g')) //-1
}

//返回字符串中函数f(r)=true手册出现的位置
func s12() {
    f := func(c rune) bool {
        //判断是否为中文
        return unicode.Is(unicode.Han, c)
    }
    fmt.Println(strings.IndexFunc("hello123,中国", f)) //9
}

//返回字符串中子串最后一次出现的位置
func s13() {
    fmt.Println(strings.LastIndex("google", "o"))
}

//字符串切割为切片
func s14() {
    str := "abc.jpg"
    s1 := strings.Split(str, ".")
    fmt.Println(s1[len(s1)-1])
}

//字符串切割
//将字符串以空格分隔
func s15() {
    fmt.Println(strings.Fields("I have a dog"))
}

//将字符串以满足f(r)=true的字符分隔,返回一个切片
func s16() {
    f := func(c rune) bool {
        //返回非字符,非数字
        return !unicode.IsLetter(c) && !unicode.IsNumber(c)
    }
    fmt.Println(strings.FieldsFunc("abc@2323#ewffw", f))
}

//将字符串以sep作为分隔符进行切割,分隔后最后去掉sep
func s17() {
    fmt.Printf("%q
", strings.Split("a,b,c", ","))
    fmt.Printf("%q
", strings.Split("a man a plan a cannel", "a"))
    fmt.Printf("%q
", strings.Split("xyz", ""))
    fmt.Printf("%q
", strings.Split("", "bern"))
    fmt.Printf("%q
", strings.SplitN("a,b,c", ",", 2))
    fmt.Printf("%q
", strings.SplitN("bern", "", 2))
}

//分割后附上sep
func s18() {
    fmt.Println(strings.SplitAfter("a,b,c", ","))
}

//大小转化

//字符串每个单词首字母大写
func s19() {
    fmt.Println(strings.Title("her royal highness"))
}

//将字符串转大写
func s20() {
    fmt.Println(strings.ToTitle("louD noises"))
}

//转小写
func s21() {
    fmt.Println(strings.ToLower("I have a Dog"))
}

//字符串转成大写返回
func s22() {
    fmt.Println(strings.ToUpper("I have a Dog"))
}

//修剪字符串

//将字符串s首位包含在cutset中的任一字符去掉返回
func s23() {
    fmt.Println(strings.Trim("  steven wang  ", " "))
}

//将字符串s首尾满足函数f(r)=true 的字符去掉
func s24() {
    f := func(c rune) bool {
        return !unicode.IsLetter(c) && !unicode.IsNumber(c)
    }
    //去除非字符和数字
    fmt.Println(strings.TrimFunc("!@steven@$#hello@#@", f))
}

//清除左侧字符
func s25() {
    fmt.Print(strings.TrimLeft(" sddddddg  ", " "))
    fmt.Print(strings.TrimRight(" sddddddg  ", " "))
    fmt.Print("aa")
}

//
//将字符串s首尾满足函数f(r)=true 的字符去掉
func s26() {
    f := func(c rune) bool {
        return !unicode.IsLetter(c) && !unicode.IsNumber(c)
    }
    //去除非字符和数字
    fmt.Println(strings.TrimLeftFunc("!@steven@$#hello@#@", f))
    fmt.Println(strings.TrimRightFunc("!@steven@$#hello@#@", f))
}

//去除首尾空格
func s27() {
    fmt.Println(strings.TrimSpace(" 	
 a lone gopher 
	
"))
}

//去除前缀
func s28() {
    s := "Goodbye,world"
    fmt.Println(strings.TrimPrefix(s, "Goodbye"))
    fmt.Println(strings.TrimSuffix(s, "world"))
}

//比较字符串大小
func s29() {
    fmt.Println(strings.Compare("abc", "cde"))
    fmt.Println("abc" < "cde")
}

//两个utf8字符串是否相等
func s30(){
    fmt.Println(strings.EqualFold("Go","go"))
}
//将字符串重复n次返回
func s31(){
    fmt.Println(strings.Repeat("abc",3))
}
//字符串替换
func s32(){
    fmt.Println(strings.Replace("jack rose","e","r",-1))
}
//切片转字符串
func s33(){
    s:=[]string{
        "abc",
        "ABC",
        "123",
    }
    fmt.Println(strings.Join(s,","))
}
View Code

strconv使用  字符串相关的类型转换

//字符串转为其他类型
//字符串转int
func s34(){
    a,_:=strconv.Atoi("100")
    fmt.Printf("%T,%v
",a,a)
}
//解释给定基数的字符串s,并返回相应的值i
func s35(){
    //转为10进制
    num,_:=strconv.ParseInt("-4e00",16,64)
    fmt.Printf("%T,%v
",num,num)
    //转10进制
    num,_=strconv.ParseInt("01100001",2,64)
    fmt.Printf("%T,%v
",num,num)
    //输出二进制
    num,_=strconv.ParseInt("-01100001",10,64)
    fmt.Printf("%T,%v
",num,num)
    //输出
    num,_=strconv.ParseInt("4e00",16,64)
    fmt.Printf("%T,%v
",num,num)
    //
    num,_=strconv.ParseInt("5778",10,64)
    fmt.Printf("%T,%v
",num,num)
}
//转为无符号类型
func s36(){
    //转为10进制
    num,_:=strconv.ParseUint("-4e00",16,64)
    fmt.Printf("%T,%v
",num,num)
    //转10进制
    num,_=strconv.ParseUint("01100001",2,64)
    fmt.Printf("%T,%v
",num,num)
    //输出二进制
    num,_=strconv.ParseUint("-01100001",10,64)
    fmt.Printf("%T,%v
",num,num)
    //输出
    num,_=strconv.ParseUint("4e00",16,64)
    fmt.Printf("%T,%v
",num,num)
    //
    num,_=strconv.ParseUint("5778",10,64)
    fmt.Printf("%T,%v
",num,num)
}

//将字符串s转换为float类型
func s37(){
    pi:="3.1415926"
    num,_:=strconv.ParseFloat(pi,64)
    fmt.Printf("%T,%v
",num,num+2)
    fmt.Println("----------")
}

//字符串转bool类型
func s38(){
    flag,_:=strconv.ParseBool("false")
    fmt.Printf("%T,%v
",flag,flag)
    fmt.Println("------")
}
View Code

format使用 字符串相关的类型转换

//将其他类型格式化为字符串
//int转为字符串
func f1(){
s:=strconv.Itoa(199)
fmt.Printf("%T,%v,len=%d
",s,s,len(s))
}
//返回给定基数的i的字符串表示
func f2(){
s:=strconv.FormatInt(-19968,16)
s=strconv.FormatInt(-40869,16)
fmt.Printf("%T,%v,len=%d
",s,s,len(s))
}
//返回给定基数的i的字符串表示,无符号
func f3(){
    s:=strconv.FormatUint(19968,16)
    s=strconv.FormatUint(40869,16)
    fmt.Printf("%T,%v,len=%d
",s,s,len(s))
}
//将浮点数转为字符串
func f4(){
    s:=strconv.FormatFloat(3.1415926,'g',-1,64)
    fmt.Printf("%T,%v,len=%d",s,s,len(s))
}
func main() {
    f4()
}
View Code

常量

package main
import (
    
    "fmt"
)
func main() {

    var num int
    num = 9 //ok
    //常量声明的时候,必须赋值。
    const tax int = 0 
    //常量是不能修改
    //tax = 10
    fmt.Println(num, tax)
    //常量只能修饰bool、数值类型(int, float系列)、string 类型
    
    //fmt.Println(b)

    const (
        a = iota
        b 
        c
        d
    )


    fmt.Println(a, b, c, d)
}
View Code

 数组

package main

import "fmt"

//定义长度为三的数组
//数组的长度一旦定义不可修改
//长度是数组类型的一部分

//二维数组
func a5() {
    a := [3][2]string{
        {"北京", "上海"},
        {"广州", "深圳"},
        {"成都", "重庆"},
    }
    fmt.Println(a)
    fmt.Println(a[2][1])
}

//数组的遍历
func a4() {
    var a = [...]string{"北京", "上海", "深圳"}
    for i := 0; i < len(a); i++ {
        fmt.Println(a[i])
    }
}

//指定索引初始化数组
func a3() {
    a := []int{1: 1, 3: 5}
    fmt.Println(a)
    fmt.Printf("%T
", a)
}
func a2() {
    var testArray [3]int
    var numArray = []int{1, 2}
    //自行推断数组长度
    var cityArray = [...]string{"北京", "上海", "深圳"}
    fmt.Println(testArray)
    fmt.Println(numArray)
    fmt.Println(cityArray)
    fmt.Printf("%T
", cityArray)
}

func main1() {
    var testArray [3]int
    var numArray = [3]int{1, 2}
    var cityArray = [3]string{"北京", "上海", "深圳"}
    fmt.Println(testArray)
    fmt.Println(numArray)
    fmt.Println(cityArray)
}

//二位数组只有第一层可以使用...

func modif1(x [3]int) {
    x[0] = 100
}
func modif2(x [3][2]int) {
    x[2][0] = 100
}

func a6() {
    a := [3]int{10, 20, 30}
    modif1(a)
    fmt.Println(a)
    b := [3][2]int{
        {1, 1},
        {1, 1},
        {1, 1},
    }
    modif2(b)
    fmt.Println(b)
}

//求数组[1, 3, 5, 7, 8]所有元素的和
func arr7() {
    a := [5]int{1, 3, 5, 7, 8}
    var lg int = len(a)
    sum :=0
    for i := 0; i < lg; i++ {
        sum += a[i]
        fmt.Println(a[i])
    }
    fmt.Println(sum)
}
View Code

示例

package main

import "fmt"

import "math/rand"

import "time"

func a1() {

    var intArr [3]int
    //数组定以后每个元素的地址为0
    //地址占用八个字接
    fmt.Println(intArr)
    intArr[0] = 10
    intArr[1] = 20
    intArr[2] = 30
    fmt.Println(intArr)
    fmt.Printf("intArr地址%p
 intArr[0]地址%p
intArr[1]地址%p
,intArr[2]地址%p",
        &intArr, &intArr[0], &intArr[1], &intArr[2])
    fmt.Printf("类型%T", intArr[1])
}

//for-range遍历数组
func a2() {
    //长度填...表示自动推导,但不可为空
    heroes := [...]string{"宋江", "吴用", "卢俊义"}

    for i, v := range heroes {
        fmt.Printf("i=%v, v=%v
", i, v)
    }
}

//数组可以采用内存调用速度更快
//数组属于值类型,因此会进行值拷贝
//修改数组,采用引用传值
func a3(arr *[3]int) {
    //数组【下标】
    (*arr)[0] = 99
}

//创建一个byte类型,的26个元素的数组,分别放A-Z,并打印
func a4() {
    var myChars [26]byte
    for i := 0; i < 26; i++ {
        //i类型转换并相加
        myChars[i] = 'A' + byte(i)
    }

    for i := 0; i < 26; i++ {
        fmt.Printf("%c-%v
", myChars[i], myChars[i])
    }
}

//求数组中最大值
func a5() {
    var intArr [6]int = [...]int{1, -1, 9, 90, 11, 98000}
    maxVal := intArr[0]
    maxValIndex := 0
    for i := 1; i < len(intArr); i++ {
        if maxVal < intArr[i] {
            maxVal = intArr[i]
            maxValIndex = i
        }

    }
    fmt.Printf("maxVal=%v maxValIndex=%v", maxVal, maxValIndex)
}

//求数组平均值
func a6() {
    var intArr2 [5]int = [...]int{1, -1, 9, 90, 12}
    sum := 0
    for _, v := range intArr2 {
        sum += v
    }
    fmt.Printf("sum=%v,avg=%v", sum, float64(sum)/float64(len(intArr2)))
}

//生成五个随机数,并反转打印
func a7() {
    var intArr3 [5]int
    len := len(intArr3)
    rand.Seed(time.Now().UnixNano())
    for i := 0; i < len; i++ {
        intArr3[i] = rand.Intn(100)
    }
    fmt.Println("交换前=", intArr3)
    temp := 0
    for i := 0; i < len/2; i++ {
        temp = intArr3[len-1-i]
        intArr3[len-1-i] = intArr3[i]
        intArr3[i] = temp
    }
    fmt.Println("交换后=", intArr3)
}
func main() {
    a6()
}
View Code

 排序与查找

package main

import (
    "fmt"
)

//冒泡排序
func BubbleSort(arr *[5]int) {
    fmt.Println("排序前arr=", (*arr))

    for i := 0; i < len(*arr)-1; i++ {
        for j := 0; j < len(*arr)-1-i; j++ {
            if (*arr)[j] > (*arr)[j+1] {
                //交换
                (*arr)[j], (*arr)[j+1] = (*arr)[j+1], (*arr)[j]
            }
        }
    }
}

//顺序查找
func s1() {
    names := [4]string{"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"}
    var heroName = ""
    fmt.Println("请输入要查找的人名")
    fmt.Scanln(&heroName)
    //方式一
    //for i := 0; i < len(names); i++ {
    //    if heroName == names[i] {
    //        fmt.Printf("找到%v,下标%v 
", heroName,i)
    //        break
    //    } else if i == (len(names) - 1) {
    //        fmt.Printf("没有找到%v
", heroName)
    //    }
    //
    //}
    //方式二:分两步处理
    index:= -1
    for i := 0; i < len(names); i++ {
        if heroName == names[i] {
            index = i
            break
        }
    }
    if index != -1 {
        fmt.Printf("找到%v, 下标%v 
", heroName, index)
    } else {
        fmt.Println("没有找到", heroName)
    }
}

//二分法查找
func BinaryFind(arr *[6]int,leftIndex int,rightIndex int,findVal int){
    //判断leftIndex是否大于rightIndex
    if leftIndex>rightIndex{
        fmt.Println("找不到")
        return
    }
    //先找到中间下标
    middle:=(leftIndex+rightIndex)/2
    if(*arr)[middle]>findVal{
        //要查找的值在leftIndex--middle中
        BinaryFind(arr,leftIndex,rightIndex,findVal)
    }else if (*arr)[middle]<findVal{
        BinaryFind(arr,middle+1,rightIndex,findVal)
    }else{
        fmt.Printf("找到了,下表为%v
",middle)
    }
}



func main() {
    // arr := [5]int{24, 69, 80, 57, 13}
    // BubbleSort(&arr)
    // fmt.Println("main arr=", arr)
    //s1()
    arr:=[6]int{1,8,10,89,1000,1234}
    BinaryFind(&arr,0,len(arr)-1,1234)
}
View Code

二维数组

/*
二维数组

*/
func a8() {
    var arr [4][6]int
    arr[1][2] = 1
    arr[2][1] = 2
    arr[2][3] = 3
    for i := 0; i < 4; i++ {
        for j := 0; j < 6; j++ {
        //    fmt.Print(arr[i][j], " ")
        //打印内存地址
            fmt.Printf("%p  ",&arr[i][j])
        }
        fmt.Println()
    }
}

//内存地址分析
func a9() {
    //先声明后赋值
    var arr2 [2][3]int
    arr2[1][1] = 10
    fmt.Println(arr2)
    fmt.Printf("arr2[0]的地址%p
", &arr2[0])
    fmt.Printf("arr2[1]的地址%p
", &arr2[0][0])
    fmt.Printf("arr2[1][0]的地址%p
", &arr2[1][0])
}
func a10(){
    //直接初始化
    var arr3 [2][3]int=[2][3]int{{1,2,3},{4,5,6}}
    fmt.Println(arr3)
}
//二位数组的遍历
func a11(){
    var arr3=[2][3]int{{1,2,3},{4,5,6}}
    for i:=0;i<len(arr3);i++{
        for j:=0;j<len(arr3[i]);j++{
            fmt.Printf("%v	",arr3[i][j])
        }
        fmt.Println()
    }

    //使用for-range遍历
    for k,v:=range arr3{
        for k2,v2:=range v{
            fmt.Printf("arr3[%v][%v]=%v	",k,k2,v2)
        }
    fmt.Println()
    }

}

//应用案例
func a12(){
    var scores [3][5]float64
    for i:=0;i<len(scores);i++{
        for j:=0;j<len(scores[i]);j++{
            fmt.Printf("请输入第%d班第%d个学生的成绩
",i+1,j+1)
            fmt.Scanln(&scores[i][j])
        }
    }
    totalSum:=0.0
    for i:=0;i<len(scores);i++{
        sum:=0.0
        for j:=0;j<len(scores[i]);j++{
            sum+=scores[i][j]
        }
        totalSum+=sum
        fmt.Printf("第%d班级的总分为%v
",i+1,sum,sum/float64(len(scores[i])))
    }
    fmt.Printf("所有班级的总分为%v,所有班级平均分为%v
",
        totalSum,totalSum/15)

}
View Code

切片

package main

import "fmt"

//数组求和
func s1(x [3]int) {
    sum := 0
    for _, v := range x {
        sum += v
    }
    fmt.Println(sum)
}

//声明切片类型
func s2() {
    //
    var a []string
    var b = []int{}
    var c = []bool{false, true}
    //var d = []bool{false, true}
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)
    fmt.Println(a == nil)
    fmt.Println(b == nil)
    fmt.Println(c == nil)
    //fmt.Println(c==d)

}
//基于数组定义切片
func s3(){
    a:=[5]int{55,56,57,58,59}
    b:=a[1:4]
    fmt.Println(b)
    fmt.Println(a[1:])
    fmt.Println(a[:4])
    fmt.Println(a[:])
    fmt.Printf("%T
",b)
}
View Code

测试

package main

import "fmt"

/*

1.切片是引用类型
2.切片是可动态变化的数组
*/
//切片的基本使用
func q1() {
    var intArr [5]int = [...]int{1, 22, 33, 66, 99}
    slice := intArr[1:3]
    fmt.Println("intArr=", intArr)
    fmt.Println("slice的元素", slice)
    fmt.Println("slice长度", len(slice))
    fmt.Println("slice容量", cap(slice))
    fmt.Printf("slice的类型%T", slice)
}

//声明切片
func q2() {
    //方式一
    var intArr [5]int = [...]int{1, 22, 33, 66, 99}
    fmt.Println(intArr)
    //方式二:使用make,由切片底层维护
    var intArr2 []int = make([]int, 4, 10)
    fmt.Println(intArr2)
    //方式三
    var strSlice []string = []string{"tom", "jack", "mary"}
    fmt.Println(strSlice)
}

//切片的遍历
func q3() {
    var arr [5]int = [...]int{10, 20, 30, 40, 50}
    slice := arr[1:4]
    for i := 0; i < len(slice); i++ {
        fmt.Printf("slice[%v]=%v", i, slice[i])
    }
    fmt.Println()
    for i, v := range slice {
        fmt.Printf("i=%v v=%v
", i, v)
    }
}

//切片可以进行再次切片
//append动态追加
func q4() {
    var slice3 []int = []int{100, 200, 300}
    fmt.Println("slice3", slice3)
    //切片追加
    slice3 = append(slice3, slice3...)
    fmt.Println("slice3", slice3)
}

//拷贝操作
func q5() {
    var slice4 []int = []int{1, 2, 3, 4, 5}
    var slice5 = make([]int, 10)
    copy(slice5, slice4)
    fmt.Println("clice4=", slice4)
    fmt.Println("slice5", slice5)
}

//切片实现斐波那契数列
func fbn(n int) []uint64 {
    fbnSlice := make([]uint64, n)
    fbnSlice[0] = 1
    fbnSlice[1] = 1
    for i := 2; i < n; i++ {
        fbnSlice[i] = fbnSlice[i-1] + fbnSlice[i-2]
    }
    return fbnSlice
}
func main() {
    fbnSlice := fbn(20)
    fmt.Println("fbnSlice=", fbnSlice)
}
View Code

删除切片

m1=append(m1[:1],m1[2:]...)

map

package main

import (
    "fmt"
    "sort"
)

//初始化
func m1() {
    //方式一
    var a map[string]string
    a = make(map[string]string, 10)
    a["n1"] = "宋江"
    a["n2"] = "吴用"
    a["n3"] = "武松"
    a["n4"] = "吴用"
    fmt.Println(a)
    //方式二
    cities := make(map[string]string)
    cities["no1"] = "北京"
    cities["no2"] = "天津"
    cities["no3"] = "上海"
    fmt.Println(cities)

    //方式三
    heroes := map[string]string{
        "hero1": "宋江",
        "hero2": "卢俊义",
        "hero3": "吴用",
    }
    heroes["hero4"] = "林冲"
    fmt.Println("hreoes=", heroes)
}

//二维map
func m2() {
    studentMap := make(map[string]map[string]string)
    studentMap["stu01"] = make(map[string]string)
    studentMap["stu01"]["name"] = "tom"
    studentMap["stu01"]["sex"] = ""
    studentMap["stu01"]["address"] = "长安街"

    studentMap["stu02"] = make(map[string]string)
    studentMap["stu02"]["name"] = "marry"
    studentMap["stu02"]["sex"] = ""
    studentMap["stu02"]["address"] = "黄浦江"
    fmt.Println(studentMap)
    fmt.Println(studentMap["stu02"])
    fmt.Println(studentMap["stu02"]["address"])

}

//删除
func m3() {
    cities := make(map[string]string)
    cities["no1"] = "北京"
    cities["no2"] = "天津"
    cities["no3"] = "上海"
    fmt.Println(cities)
    delete(cities, "no2")
    fmt.Println(cities)
}

//判断元素是否存在
func m4() {
    cities := make(map[string]string)
    cities["no1"] = "北京"
    cities["no2"] = "天津"
    cities["no3"] = "上海"
    val, ok := cities["no2"]
    if ok {
        fmt.Printf("no2的值为%v", val)
    } else {
        fmt.Println("找不到")
    }

}

//map遍历
func m5() {
    cities := make(map[string]string)
    cities["no1"] = "北京"
    cities["no2"] = "天津"
    cities["no3"] = "上海"
    for k, v := range cities {
        fmt.Printf("k=%v v=%v
", k, v)
    }
    studentMap := make(map[string]map[string]string)
    studentMap["stu01"] = make(map[string]string, 3)
    studentMap["stu01"]["name"] = "tom"
    studentMap["stu01"]["sex"] = ""
    studentMap["stu01"]["address"] = "长安街"

    studentMap["stu02"] = make(map[string]string, 3)
    studentMap["stu02"]["name"] = "marry"
    studentMap["stu02"]["sex"] = ""
    studentMap["stu02"]["address"] = "黄浦江"

    for k1, v1 := range studentMap {
        fmt.Println("k1=", k1)
        for k2, v2 := range v1 {
            fmt.Printf("	 k2=%v v2=%v
", k2, v2)
        }
        fmt.Println()
    }
}

//map切片
func m6() {
    var monsters []map[string]string
    monsters = make([]map[string]string, 2)
    if monsters[0] == nil {
        monsters[0] = make(map[string]string, 2)
        monsters[0]["name"] = "牛魔王"
        monsters[0]["age"] = "500"
    }
    if monsters[1] == nil {
        monsters[1] = make(map[string]string, 2)
        monsters[1]["name"] = "玉兔精"
        monsters[1]["age"] = "400"
    }

    newMOnstr := map[string]string{
        "name": "火云邪神",
        "age":  "200",
    }
    monsters = append(monsters, newMOnstr)
    fmt.Println(monsters)

}

//map排序
func m7() {
    map1 := make(map[int]int, 10)
    map1[10] = 100
    map1[1] = 13
    map1[4] = 56
    map1[8] = 90
    fmt.Println(map1)

    var keys []int
    for k, _ := range map1 {
        keys = append(keys, k)
    }
    sort.Ints(keys)
    fmt.Println(keys)
    for _, k := range keys {
        fmt.Printf("map1[%v]=%v 
", k, map1[k])
    }
}

//map是引用类型,修改值后会影响原来的
//会自动扩容

//结构体
//func m8(){
//    students:=make(map[string]Stu,10)
//    stu1:=Stu{"tom",18,"北京"}
//    stu2:=Stu{"mary",17,"上海"}
//students["no1"]=stu1
//students["no2"]=stu2
//fmt.Sprintln(students)
//for k,v:=range students{
//    //fmt.Printf("学生的编号%v,名字:%v,年龄:%v,地址:%v
",k,v.Name,v.Age,v.Address)
//}
//}

//查找用户存在则修改,不存在则添加
func modifyUser(users map[string]map[string]string, name string) {
    //用户是否存在
    if users[name] == nil {
        users[name]["pwd"] = "888888"
    } else {
        users[name] = make(map[string]string, 2)
        users[name]["pwd"] = "888888"
        users[name]["nickname"] = "昵称~" + name
    }
}

func main() {
    users := make(map[string]map[string]string, 10)
    users["smith"] = make(map[string]string, 2)
    users["smith"]["pwd"] = "999999"
    users["smith"]["nickname"] = "小花猫"
    modifyUser(users, "tom")
    modifyUser(users, "mary")
    modifyUser(users, "smith")
    fmt.Sprintln(users)
}
View Code

删除map

重新make一个
m1=make(map[int]string)
m1=nil
View Code

流程控制

 顺序

循环

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func f1() {
    j := 1
    for j <= 10 {
        fmt.Println(j)
        j++
    }
}

func f2() {
    k := 1
    for {
        if k <= 10 {
            fmt.Println(k)
        } else {
            break
        }
        k++
    }
}

func f3() {
    var str string = "hello world !"
    for i := 0; i < len(str); i++ {
        fmt.Printf("%c
", str[i])
    }
}
func f4() {
    str := "abc~ok"
    for index, val := range str {
        fmt.Printf("index=%d val=%c 
", index, val)
    }
}

//有中文时遍历

func f5() {
    str := "abc~ok上海"
    for index, val := range str {
        fmt.Printf("index=%d val=%c 
", index, val)
    }
}

//使用切片遍历中文
func f6() {
    var str string = "hello world!北京"
    str2 := []rune(str)
    for i := 0; i < len(str2); i++ {
        fmt.Printf("%c
", str2[i])
    }
}

//break 使用
func f7() {
    var count int = 0
    for {
        rand.Seed(time.Now().UnixNano())
        n := rand.Intn(100) + 1
        fmt.Println("n=", n)
        count++
        if n == 99 {
            break
        }
    }
    fmt.Printf("生成99一共使用了%d次", count)
}

//通过标签终止
func f8() {
    //label2:
    for i := 0; i < 4; i++ {
        //label1:
        for j := 0; j < 10; j++ {
            if j == 2 {
                break
            }
            fmt.Printf("%d-%d
", i, j)
        }
    }
}

//continue的使用
func f9() {
    for i := 0; i < 4; i++ {
        if i == 2 {
            continue
        }
        fmt.Println("i=", i)
    }
}

//
func f10() {
here:
    for i := 0; i < 2; i++ {
        for j := 0; j < 4; j++ {
            if j == 2 {
                continue here
            }
            fmt.Printf("i=%v j=%v
", i, j)
        }

    }
}

//打印菱形
/*

********
 *      *
  *      *
   *      *
    ********
*/

func f11() {
    var height int = 30 //
    var width int = 30  //
    for i := 1; i <= height; i++ {
        //打空格
        for j := 1; j <= i-1; j++ {
            fmt.Print(" ")
        }
        //打星
        for j := 1; j <= width; j++ {
            if (i == 1 || i == height) || (j == 1 || j == width) {
                fmt.Print("* ")
            } else {
                fmt.Print("  ")
            }
        }
        fmt.Println()
    }

}
func main() {
    f11()
}
View Code

分支

循环

9*9乘法口诀

//打印99乘法口诀
func formula() {
    for i := 1; i < 10; i++ {
        for j := 1; j < 10; j++ {
            if i <= j {
                fmt.Printf("%v*%v=%v ", i, j, i*j)
            }
        }
        fmt.Println("
")
    }
}
View Code

 goto

//goto 的使用
func main() {
    var n int = 30
    fmt.Println("ok1")
    fmt.Println("ok2")
    if n > 20 {
        goto label
    }
    fmt.Println("ok3")
    fmt.Println("ok4")
label:
    fmt.Println("ok5")
}
View Code

函数

基础使用

func cal(n1 float64, n2 float64, operator byte) float64 {
    var res float64
    switch operator {
    case '+':
        res = n1 + n2
    case '-':
        res = n1 - n2
    case '*':
        res = n1 * n2
    case '/':
        res = n1 / n2
    default:
        fmt.Println("输入错误")

    }
    return res
}

//求和与差,函数返回两个结果
func getSumAndSub(n1 int, n2 int) (int, int) {
    sum := n1 + n2
    sub := n1 - n2
    return sum, sub
}
View Code

递归

//递归函数,递减内容
func test(n int) {
    if n > 2 {
        n--
        test(n)
    }
    fmt.Println("n=", n)
    //回归时输出2,2,3,回归与递进方向相反
}

//改进版
func test2(n int) {
    if n > 2 {
        n--
        test2(n)
    } else {
        fmt.Println("n=", n)
    }
}
View Code

值传递

//基本数据类型和数组默认都是值传递,即进行值拷贝,在函数内修改,不会影响原来的值。
func test02(n1 int) {
    n1 = n1 + 10
    fmt.Println("test02 n1=", n1)
}

func main() {
     num := 20
    /test02(num)
     fmt.Println("main() num=", num)

}
View Code

函数作为数据类型

func getSum(n1 int, n2 int) int {
    return n1 + n2

}
func myFun(funvar func(int, int) int, num1 int, num2 int) int {

    return funvar(num1, num2)

}

func main() {
    res2 := myFun(getSum, 50, 60)
    fmt.Println("res2=", res2)
}
View Code

自定义数据类型

//自定义数据类型
func f1() {
    //给int类型取别名,在go中会认为是两个数据类型

    type myint int
    var num1 myint
    var num2 int
    num1 = 40
    num2 = int(num1) //这里需要显示转换
    fmt.Println("num1=", num1, "num2=", num2)
    fmt.Printf("num1类型%T,num2类型%T", num1, num2)

}
func getSum(num1 int, num2 int) int {
    return num1 + num2
}

//定义一个函数为数据类型
type myFunType func(int, int) int

func myFun2(funvar myFunType, num1 int, num2 int) int {
    return funvar(num1, num2)
}

func main() {
    res3 := myFun2(getSum, 500, 600)
    fmt.Println("res3=", res3)
}
View Code

支持函数返回值命名

//支持函数返回值命名
func getSumAndSub(n1 int, n2 int) (sum int, sub int) {
    sub = n1 - n2
    sum = n1 + n2
    return
}
func main() {
    a1, b1 := getSumAndSub(1, 2)
    fmt.Printf("a1=%v,b=%v", a1, b1)
}
View Code

使用下划线忽略返回值

func getSumAndSub(n1 int, n2 int) (sum int, sub int) {
    sub = n1 - n2
    sum = n1 + n2
    return
}
func main() {
    a1, _ := getSumAndSub(1, 2)
    fmt.Printf("a1=%v", a1)
}
View Code

可变参数

//可变参数
//求1到多个int类型数的和
func sum(n1 int, args ...int) int {
    sum := n1
    for i := 0; i < len(args); i++ {
        sum += args[i]
    }
    return sum
}
func main() {
    res4 := sum(10, 23, 1)
    fmt.Printf("res4=%v", res4)
}
View Code

匿名函数

//全局匿名函数
var (
    Fun1 = func(n1 int, n2 int) int {
        return n1 * n2
    }
)

//匿名函数
func f1() {
    res1 := func(n1 int, n2 int) int {
        return n1 + n2
    }(10, 20)
    fmt.Println("res1=", res1)
}

//将匿名函数赋值给变量

func f2() {
    a := func(n1 int, n2 int) int {
        return n1 - n2
    }
    res2 := a(10, 30)
    fmt.Println("res2=", res2)

}

func main() {
    //全局匿名函数使用
    res4 := Fun1(4, 9)
    fmt.Println(res4)
}
View Code

闭包函数

package main

import "fmt"

import "strings"

//闭包函数

func AddUpper() func(int) int {
    //连续多次调用n的值被保存
    var n int = 10
    return func(x int) int {
        n = n + x
        return n
    }
}

//
func AddUpper2() func(int) int {
    var n int = 10
    var str = "hello"
    return func(x int) int {
        n = n + x
        str += string(36)
        fmt.Println("str=", str)
        return n
    }
}

//判断后缀名
func makeSuffix(suffix string) func(string) string {
    return func(name string) string {
        //如果没有指定后缀名就加上,否则直接返回
        if !strings.HasSuffix(name, suffix) {
            return name + suffix
        }
        return name
    }
}
func main() {
    // f := AddUpper2()
    // fmt.Println(f(1))
    // fmt.Println(f(2))
    // fmt.Println(f(3))

    //添加后缀名,两次传值实现
    f2 := makeSuffix(".jpg")
    fmt.Println("文件名处理后=", f2("winter"))
    fmt.Println("文件名处理后=", f2("bird.jpg"))
}
View Code

defer

package main

import "fmt"

//defer的使用
func sum(n1 int, n2 int) int {
    //当go直行到defer,不会立即执行,先压入栈,函数执行完毕后,先入后出读取
    defer fmt.Println("n1=", n1)
    defer fmt.Println("n2=", n2)
    res := n1 + n2
    fmt.Println("res=", res)
    return res
}

//在defer将语句放入栈,也会将相关的值拷贝入栈
func sum1(n1 int, n2 int) int {
    //当go直行到defer,不会立即执行,先压入栈,函数执行完毕后,先入后出读取
    defer fmt.Println("n1=", n1)
    defer fmt.Println("n2=", n2)
    n1++
    n2++
    res := n1 + n2
    fmt.Println("res=", res)
    return res
}

//defer最佳实践
//defer的价值在于当函数执行完毕后,可以及时释放函数占用的资源
//1.最后关闭文件
//2.最后断开连接

func main() {
    res := sum1(10, 20)
    fmt.Println("res=", res)
}
View Code

地址传值

//地址传值
func t1(n1 *int) {
    *n1 = *n1 + 10
}

func main() {
    num := 20
    t1(&num)
    fmt.Println("main(),num=", num)
}
View Code

其他

//未定义形参数据类型
func sum(n1, n2 float32) float32 {
    fmt.Printf("n1 type=%T
", n1)
    return n1 + n2
}

//数据交换
func swap(n1 *int, n2 *int) {
    t := *n1
    *n1 = *n2
    *n2 = t
}

func main() {
    a := 10
    b := 20
    swap(&a, &b) //传入地址
    fmt.Printf("a=%v,b=%v", a, b)
}
View Code

系统函数

字符串操作

package main

import (
    "fmt"
    "strconv"
    "strings"
)

//字符串的长度
func s1() {
    fmt.Println(len("4563"))
}

//字符串的遍历
func s2() {
    str2 := "hello北京"
    r := []rune(str2)
    for i := 0; i < len(r); i++ {
        fmt.Printf("字符串=%c
", r[i])
    }
}

//字符串转整数
func s3() {
    n, err := strconv.Atoi("234")
    if err != nil {
        fmt.Println("转换错误:", err)

    } else {
        fmt.Println("转换成功:", n)
    }
}

//整数转字符串
func s4() {
    str := strconv.Itoa(12345)
    fmt.Printf("str=%v,类型=%T", str, str)
}

//字符串转[]byte
func s5() {
    var bytes = []byte("hello go")
    fmt.Printf("bytes=%v
", bytes)
}

//[]byte转字符串
func s6() {
    str := string([]byte{97, 98, 99})
    fmt.Printf("str=%v", str)
}

//十进制转2,8,16进制
func s7() {
    str := strconv.FormatInt(123, 2)
    fmt.Printf("123对应的二进制=%v
", str)
    str = strconv.FormatInt(123, 16)
    fmt.Printf("123对应的16进制=%v", str)
}

//查找子串是否在字符串中,存在返回true,否则返回false
func s8() {
    b := strings.Contains("seafood", "ea")
    fmt.Printf("b=%v
", b)
}

//统计一个字符串中有几个指定的子串
func s9() {
    num := strings.Count("ceheese", "ee")
    fmt.Printf("num=%v
", num)
}

//字符串比较
func s10() {
    //不区分大小写
    b := strings.EqualFold("abc", "Abc")
    fmt.Printf("b=%v
", b)
    //区分大小写
    fmt.Println("结果:", "abc" == "Abc")
}

//返回子串出现的index值
func s11() {
    //返回子串第一次出现的index值
    index := strings.Index("NLT_abcabcabc", "_")
    fmt.Printf("index=%v
", index)
    //返回子串最后一次出现的index值
    index = strings.LastIndex("NLT_abcabcabc", "ab")
    fmt.Printf("last_index=%v
", index)
}

//字符串替换
func s12() {
    //-1,表示替换全部,n表示替换n个
    str := "go go hello"
    str2 := strings.Replace(str, "go", "北京", -1)
    fmt.Printf("str=%v str2=%v
", str, str2)
}

//吧字符串分割成数组
func s13() {
    strArr := strings.Split("hello,world,ok", ",")
    for i := 0; i < len(strArr); i++ {
        fmt.Printf("str[%v]=%v
", i, strArr[i])
    }
    fmt.Printf("strArr=%v
", strArr)
}

//将字符串字母大小写进行转换
func s14() {
    str := "goLang Hello"
    //全部转大写
    fmt.Println(strings.ToUpper(str))
    //全部转小写
    fmt.Println(strings.ToLower(str))
}

//去除字符串两侧空格,或其他字符
func s15() {
    fmt.Printf("str=%q
", strings.TrimSpace(" it is me "))
    fmt.Printf("str=%q
", strings.Trim("! hello kitty !", "!"))
    //去除左侧字符
    fmt.Printf("str=%q
", strings.TrimLeft("! hello kitty !", "!"))
    //去除右侧字符
    fmt.Printf("str=%q
", strings.TrimRight("! hello kitty !", "!"))
    //匹配字符串开头
    fmt.Printf("str=%v
", strings.HasPrefix("! hello kitty !", "!"))
    //匹配字符串结尾
    fmt.Printf("str=%v
", strings.HasSuffix("! hello kitty !", "!"))
}
View Code

时间和日期

import (
    "fmt"
    "time"
)

func t1() {
    now := time.Now()
    fmt.Printf("now=%v now type=%T", now, now)
    //now=2020-01-02 14:15:50.2102829 +0800 CST m=+0.012982501 now type=time.Time
}

//获取其他日期信息
func t2() {
    now := time.Now()
    fmt.Printf("年=%v
", now.Year())
    fmt.Printf("月=%v
", now.Month())
    fmt.Printf("月=%v
", int(now.Month()))
    fmt.Printf("日=%v
", now.Day())
    fmt.Printf("时=%v
", now.Hour())
    fmt.Printf("分=%v
", now.Minute())
    fmt.Printf("秒=%v
", now.Second())
}

/*
年=2020
月=January
月=1
日=2
时=14
分=19
秒=57
*/
//格式化日期
func t3() {
    now := time.Now()
    //方式一
    fmt.Printf("当前年月日 %d-%d-%d %d:%d:%d 
", now.Year(),
        now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())

    dateStr := fmt.Sprintf("当前年月日 %d-%d-%d %d:%d:%d
", now.Year(),
        now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
    fmt.Printf("dateStr=%v
", dateStr)
    //方式二  格式化日期时间的第二种方式
    fmt.Printf(now.Format("2006-01-02 15::04:05"))
    fmt.Println()
    fmt.Printf(now.Format("2006-01-02"))
    fmt.Println()
    fmt.Printf(now.Format("15:04:05"))

}

/*
时间常量


*/
// const (
//     Nanoseaond  Duration = 1                  //纳秒
//     Microsecond          = 1000 * Microsecond //微秒
//     Millisecond          = 1000 * Microsecond //毫秒
//     Second               = 1000 * Millisecond ////     Minute               = 60 * Second        //分钟
//     Hour                 = 60 * Minute
// )

//使用sleep()
func t4() {
    i := 0
    for {
        i++
        fmt.Println(i)
        time.Sleep(time.Millisecond * 1000)
        if i == 100 {
            break
        }
    }
}
func t5() {
    //unix时间戳和UnixNano时间戳
    now := time.Now()
    fmt.Printf("unix时间戳=%v unixnano=%v
", now.Unix(), now.UnixNano())
}
View Code

常用时间转换

func t1() {
    now := time.Now()
    fmt.Println(now.Unix())
    fmt.Println(now.Format("2006-01-02 15:04:05"))
    //格式化时间转为时间戳
    loc, _ := time.LoadLocation("Local") //获取时区
    tm2, _ := time.ParseInLocation("01/02/2006", "02/08/2015",loc)
    fmt.Println(tm2.Unix()) //1423353600
    //时间戳转格式化时间
    var ts int64 = 1423353600
    tm := time.Unix(ts, 0)
    fmt.Println(tm.Format("2006-01-02 03:04:05"))

}
View Code

异常处理

package main

import (
    "errors"
    "fmt"
)

//异常处理
func e1() {

    //捕捉函数内异常
    //报错后函数内终止,函数外继续执行
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println("err=", err)
        }
    }()

    num1 := 10
    num2 := 0
    res := num1 / num2
    fmt.Println("res=", res)
    fmt.Print("123")
}

//错误处理
func e2() {
    //使用defer+recover来捕捉和处理异常
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println("err=", err)
            fmt.Println("发送邮件给管理员")
        }
    }()
    num1 := 10
    num2 := 0
    res := num1 / num2
    fmt.Println("res=", res)
    fmt.Println("看不见我就对了")
}

//自定义错误

func readConf(name string) (err error) {
    if name == "config.ini" {
        return nil
    } else {
        //自定义错误
        return errors.New("读取文件错误")
    }
}

func e3() {
    err := readConf("config2.ini")
    if err != nil {
        //输出错误并终止程序
        panic(err)
    }
    fmt.Println("test02()继续执行。。。")
}


func main() {
    e3()
    fmt.Println("后面的代码")
}
View Code

 测试用例

执行所有测试

go test -v

执行指定文件

go test  -v cal_test.go

执行指定函数

go test -v -test.run TestAddUpper  

测试超时

执行指定函数

go test -v -test.run TestAddUpper   -timeout 360m

cal.go

package main

func addUpper(n int) int {
    res := 0
    for i := 1; i <= n; i++ {
        res += i
    }
    return res
}

func getSub(n1 int,n2 int) int  {
    return n1-n2

}
View Code

cal_test.go

View Code

最佳案例

monster.go

package monster

import (
    "encoding/json"
    "fmt"
    "io/ioutil"

)

type Monster struct {
    Name string
    Age int
    Skill string
}
//给Monster绑定方法Store,可以将一个MOnster变量(对象),序列化后保存到文件中
func (this *Monster) Store() bool{
    //先序列化
    data,err:=json.Marshal(this)
    if err!=nil{
        fmt.Println("marshal err=",err)
        return false
    }

    //保存到文件
    filePath:="d:/monster.ser"
    err=ioutil.WriteFile(filePath,data,0666)
    if err!=nil{
        fmt.Println("write file err=",err)
        return false
    }
    return true
}

//给MOnster绑定方法ReStore ,可以将一个序列化的MOnster,从文件中读取
//并反序列化为MOnster对象,检查反序列化,名字正确
func (this *Monster) ReStore() bool{
    //1.先从文件中,读取序列化的字符串
    filePath:="d:/monster.ser"
    data,err:=ioutil.ReadFile(filePath)
    if err!=nil{
        fmt.Println("ReadFile err=",err)
        return false
    }

    //2.使用读取到的data []byte,反序列化
    err=json.Unmarshal(data,this)
    if err!=nil{
        fmt.Println("unmarshal err=",err)
        return false
    }
    return true
}
View Code

monster_test.go

package monster

import (
    "testing"
)

//测试用例,测试 Store 方法
func TestStore(t *testing.T) {

    //先创建一个Monster 实例
    monster := &Monster{
        Name : "红孩儿",
        Age :10,
        Skill : "吐火.",
    }
    res := monster.Store()
    if !res {
        t.Fatalf("monster.Store() 错误,希望为=%v 实际为=%v", true, res)
    }
    t.Logf("monster.Store() 测试成功!")
}

func TestReStore(t *testing.T) {

    //测试数据是很多,测试很多次,才确定函数,模块..

    //先创建一个 Monster 实例 , 不需要指定字段的值
    var monster = &Monster{}
    res := monster.ReStore()
    if !res {
        t.Fatalf("monster.ReStore() 错误,希望为=%v 实际为=%v", true, res)
    }

    //进一步判断
    if monster.Name != "红孩儿" {
        t.Fatalf("monster.ReStore() 错误,希望为=%v 实际为=%v", "红孩儿", monster.Name)
    }

    t.Logf("monster.ReStore() 测试成功!")
}
View Code

命令行输入(flag)

参数输入

package main

import (
    "fmt"
    "os"
)

func main() {
fmt.Println("命令行的参数有",len(os.Args))
//遍历os.Args切片,就可以得到所有命令行参数
for i,v:=range os.Args{
    fmt.Printf("args[%v]=%v
",i,v)
}
}
View Code

格式化

package main

import (
    "flag"
    "fmt"
)

func main() {
    var user string
    var pwd string
    var host string
    var port int
    flag.StringVar(&user, "u", "", "用户名,默认为空")
    flag.StringVar(&pwd, "pwd", "", "密码默认为空")
    flag.StringVar(&host, "h", "", "主机名,默认为localhost")
    flag.IntVar(&port, "port", 3306, "主机名,默认为localhost")
    //转换
    flag.Parse()
    fmt.Printf("user=%v pwd=%v host=%v port=%v",
        user,pwd,host,port)
}
View Code

 参数输入

 go 包引入

_ "go_code/test/hello/imp"

采用下划线引入只执行包的init方法,不能调用具体方法

main.go

package main

import (
    
    _ "go_code/test/hello/imp"
)
func main() {
     imp.Print() //编译报错,说:undefined: imp
}
View Code

imp.go

package imp

import "fmt"

func init() {
    fmt.Println("imp-init() come here.")
}

func Print() {
    fmt.Println("Hello!")
}
View Code

正则匹配

注意:正则规则应该使用反引号,否则需要多加一层转义。

//匹配字节切片 判断
func r1() {
    flag, _ := regexp.Match("^\d{6,15}$", []byte("123456789"))
    fmt.Println(flag)
    flag, _ = regexp.Match("^\w{4,15}$", []byte("helo"))
    fmt.Println(flag)
}

//匹配字符串
func r2() {
    flag, _ := regexp.MatchString("^\d{4,9}", "123456")
    fmt.Println(flag)
}

//将正则表达式字符串编译成正则对象,可复用
func r3() {
    //Compile,MustCompile效果相同,compile错误返回err,MustCompile报panic
    MyRegexp, _ := regexp.Compile("^\d{6,7}\D{2}$")
    //MyRegexp2:=regexp.MustCompile("^\d{6,7}\D{2}$")
    //匹配字节数组
    res := MyRegexp.Match([]byte("123456EE"))
    fmt.Println(res)
    //判断与字符串是否匹配
    res2:=MyRegexp.MatchString("123456EE")
    fmt.Println(res2)
}
//对符合正则表达式的全部替换成指定内容
//字节数组匹配替换
func r4(){
    t:="3[a]23[ac]7[p]"
    Myregexp:=regexp.MustCompile(`w+`)
    //字节切片匹配
    res:=string(Myregexp.ReplaceAll([]byte(t),[]byte("  ")))
    fmt.Printf("%T,%v
",res,res)
    //字符串匹配
    res=Myregexp.ReplaceAllString(t,"-")
    fmt.Printf("%T,%v",res,res)
}
//通过正则切割字符串
func r5(){
    t:="第一部分#第二部分#第三部分#"
//数字表示分成几个元素
    MyRegexp:=regexp.MustCompile("#+")
    arr:=MyRegexp.Split(t,-1)
    fmt.Println(arr)
}
View Code

匹配获取内容

/*
把3[a]2[bc]ef转成
aaabcbcef
*/
func r2() {
    buf := "3[a]2[bc]ef"
    reg := regexp.MustCompile(`(d)[(w+)]`)
    reg_end := regexp.MustCompile(`w+$`)
    if reg == nil {
        fmt.Println("regexp err")
        return
    }
    res := reg.FindAllStringSubmatch(buf, -1)
    res_end := reg_end.FindAllStringSubmatch(buf, -1)
    fmt.Println(res_end[0][0])
    fmt.Println("result=", res)
    var str string
    for _, v := range res {
        //fmt.Printf("%T,v=%v
",v[1],v[1])
        var num int
        num, err := strconv.Atoi(v[1])
        if err != nil {
            fmt.Println(err)
        }

        str += strings.Repeat(v[2], num)
    }
    if res_end != nil {
        str += res_end[0][0]
    }
    fmt.Println(str)
}
View Code

 随机数

//获取0-n随机数
func r1(){
    //生成随机资源
s1:=rand.NewSource(time.Now().UnixNano())
fmt.Println(time.Now().Unix())
r1:=rand.New(s1)
randnum:=r1.Intn(10)
fmt.Println(randnum)
}
//获取0-10的随机数
func s2(){
    rand.Seed(time.Now().UnixNano())
    fmt.Println(rand.Intn(10))
    //0-1随机数
    fmt.Println(rand.Float64())
    //获取m-n的随机数
    //fmt.Println(rand.Intn(n-m+1)+m)
    m:=10
    n:=12
    fmt.Println(rand.Intn(n-m+1)+m)
}
View Code

 上下文context

context.WithCancel()

package main

import (
    "context"
    "log"
    "os"
    "time"
)

var (
    logg *log.Logger
)

func work(ctx context.Context, ch chan bool) {
    for {
        select {
        case <-ctx.Done():
            logg.Println(`打豆豆!`)
            ch <- true
            return
        default:
            logg.Println(`睡觉!`)
            time.Sleep(2 * time.Second)
        }
    }
}

func main() {
    ch := make(chan bool)
    logg = log.New(os.Stdout, "", log.Ltime)
    ctx, cancel := context.WithCancel(context.Background())
    go work(ctx, ch)
    time.Sleep(10 * time.Second)
    //取消函数:当cancel被调用时,WithCancel遍历Done以执行关闭;
    cancel()
    // 这个chan是为了保证子的goroutine执行完,当然也可以不用chan用time.Sleep停止几秒
    <-ch
    logg.Println(`吃饭!`)
}
View Code

context.WithDeadline()

package main

import (
    "context"
    "log"
    "os"
    "time"
)

var (
    logg *log.Logger
)
//返回Context和取消函数用来取消Context(这个取消函数会根据设置的时间自动取消)
func work(ctx context.Context, ch chan bool) {
    for {
        select {
        case <-ctx.Done():
            logg.Println(`打豆豆!`)
            ch <- true
            return
        default:
            logg.Println(`睡觉!`)
            time.Sleep(2 * time.Second)
        }
    }
}

func main() {
    ch := make(chan bool)
    logg = log.New(os.Stdout, "", log.Ltime)
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
    go work(ctx, ch)
    time.Sleep(10 * time.Second)
    //取消函数:当cancel被调用时,context.WithDeadline设置的时间超过了,关闭ctx.Done通道。
    cancel()
    // 这个chan是为了保证子的goroutine执行完,当然也可以不用chan用time.Sleep停止几秒
    <-ch
    logg.Println(`吃饭!`)
}
View Code

context.WithTimeout()

package main

import (
    "context"
    "log"
    "os"
    "time"
)

var (
    logg *log.Logger
)

func work(ctx context.Context, ch chan bool) {
    for {
        select {
        case <-ctx.Done():
            logg.Println(`打豆豆!`)
            ch <- true
            return
        default:
            logg.Println(`吃饭!`)
            time.Sleep(2 * time.Second)
        }
    }
}
//context.WithCancel():执行取消函数就取消
//context.WithDeadline、context.WithTimeout:超时的时候就取消
func main() {
    ch := make(chan bool)
    logg = log.New(os.Stdout, "", log.Ltime)
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    go work(ctx, ch)
    time.Sleep(10 * time.Second)
    //取消函数:当cancel被调用时,context.WithTimeout设置的时间超过后,关闭ctx.Done通道;
    cancel()
    // 这个chan是为了保证子的goroutine执行完,当然也可以不用chan用time.Sleep停止几秒
    <-ch
    logg.Println(`睡觉!`)
}
View Code

Deadline

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"
)

var (
    logg *log.Logger
)

func work(ctx context.Context, ch chan bool) {
    for {
        /*
           Deadline:是获取设置的超时时间:
           第一个返回值:设置的超时时间,到超时时间Context会自动发起取消请求
           第二个返回值ok==false时表示没有设置截止时间,如果需要取消的话需要调用取消函数进行取消。
        */
        if deadline, ok := ctx.Deadline(); ok {
            fmt.Println(deadline)
            if time.Now().After(deadline) {
                logg.Println(`超时退出!`)
                //这里是为了演示,Context中的Err()输出:context deadline exceeded
                logg.Printf(ctx.Err().Error())
                ch <- true
                return
            }

        }
        select {
        case <-ctx.Done():
            logg.Println(`下班!`)
            ch <- true
            return
        default:
            logg.Println(`上班!`)
            time.Sleep(1 * time.Second)
        }
    }
}

func main() {
    ch := make(chan bool)
    logg = log.New(os.Stdout, "", log.Ltime)
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    go work(ctx, ch)
    time.Sleep(10 * time.Second)
    //取消函数:当cancel被调用时,context.WithTimeout设置的时间超过后,关闭ctx.Done通道;
    cancel()
    // 这个chan是为了保证子的goroutine执行完,当然也可以不用chan用time.Sleep停止几秒
    <-ch
    logg.Println(`无脑发呆中!`)
}
View Code

context.WithValue

package main

import (
    "context"
    "fmt"
)

func main() {
    ProcessRequest("jane", "abc123")
}

type ctxKey int

const (
    ctxUserName ctxKey = iota
    ctxPassWord
)
//上下文数据存取
func UserName(c context.Context) string {
    return c.Value(ctxUserName).(string)
}

func PassWord(c context.Context) string {
    return c.Value(ctxPassWord).(string)
}

func ProcessRequest(UserName, PassWord string) {
    ctx := context.WithValue(context.Background(), ctxUserName, UserName)
    ctx = context.WithValue(ctx, ctxPassWord, PassWord)
    HandleResponse(ctx)
}

func HandleResponse(ctx context.Context) {
    fmt.Printf(
        "处理响应 用户名:%v 密码:%v",
        UserName(ctx),
        PassWord(ctx),
    )
}
/*  outfile:
处理响应 用户名:jane 密码:abc123
*/
View Code

。。。。

原文地址:https://www.cnblogs.com/huay/p/12033391.html