zoukankan      html  css  js  c++  java
  • 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

    。。。。

  • 相关阅读:
    BZOJ 3611: [Heoi2014]大工程 [虚树 DP]
    BZOJ 3991: [SDOI2015]寻宝游戏 [虚树 树链的并 set]
    BZOJ 2286: [Sdoi2011消耗战 [DP 虚树]
    BZOJ 4767: 两双手 [DP 组合数]
    BZOJ 1426: 收集邮票 [DP 期望 平方]
    转「服务器运维」如何解决服务器I/O过高的问题
    iostat查看linux硬盘IO性能
    Linux前台、后台、挂起、退出、查看命令汇总
    Linux虚拟内存的作用
    -bash: iostat: command not found解决办法
  • 原文地址:https://www.cnblogs.com/huay/p/12033391.html
Copyright © 2011-2022 走看看