zoukankan      html  css  js  c++  java
  • go笔记3

    package main
    
    import (
        "container/list"
        "fmt"
        "math"
        "sort"
        "strings"
        "sync"
    )
    
    const (
        Unknown = 0
        Female  = 1
        Male    = 2
    )
    
    func main() {
        var (
            a int
            b string
        )
        c := 10
        d := 20
    
        //交换变量值
        d, c = c, d
        fmt.Println(d)
        fmt.Println(c)
        fmt.Println(a)
        fmt.Println(b)
        fmt.Println("hello world")
    
        e, _ := getData()
        _, f := getData()
        fmt.Println(e)
        fmt.Println(f)
        //g1 := true
        //使用反引号`定义多行字符串:
        var temp string
        temp = `
            x := 10
            y := 20
            z := 30
            fmt.Println(x, "  ", y, "  ", z)
            x, y, z = y, z, x
            fmt.Println(x, "  ", y, "  ", z)
        `
        fmt.Println(temp)
        //Go语言数据类型转换
        //浮点型与整型之间的转换
        chinese := 90
        english := 80.9
        avg := (chinese + int(english)) / 2
        avg2 := (float64(chinese) + english) / 2
        fmt.Printf("%T, %d
    ", avg, avg)
        fmt.Printf("%T, %f
    ", avg2, avg2)
        //:在Go语言中,不允许字符串转 int,否则会产生如下错误。
        //常量
        fmt.Println(Unknown, Female, Male)
    
        var aa bool = true
        var ba bool = false
        if aa && ba {
            fmt.Printf("第一行 - 条件为 true 
    ")
        }
        if aa || ba {
            fmt.Printf("第二行 - 条件为 true 
    ")
        }
    
        num := 20
        if num%2 == 0 {
            fmt.Println(num, "是偶数")
        } else {
            fmt.Println(num, "是奇数")
        }
        //在定义时调用匿名函数
        func(data int) {
            fmt.Println("hello", data)
        }(100)
        // 将匿名函数赋值给变量
        ff := func(datas string) {
            fmt.Println(datas)
        }
        ff("将匿名函数赋值给变量")
        //匿名函数用作回调函数
        // 调用函数,对每个元素进行求平方根操作
        arr := []float64{1, 9, 16, 25, 30}
        // 调用函数,对每个元素进行求平方根操作
        visit(arr, func(v float64) {
            v = math.Pow(v, 2)
            fmt.Printf("%.0f 
    ", v)
        })
    
        var nums = [...]int{1, 2, 3, 4, 5}
        fmt.Printf("数组 a 的长度为 %d,数组 b 的长度为 %d
    ", len(nums), len(nums))
        //遍历数组方式1
        for i := 0; i < len(nums); i++ {
            fmt.Print(nums[i], "	")
        }
        fmt.Println()
        //遍历数组方式2
        for _, value := range nums {
            fmt.Print(value, "	")
        }
    
        //三行  每行4个值得二维数组
        erweiarr := [3][4]int{
            {0, 1, 2, 3},   /* 第一行索引为0 */
            {4, 5, 6, 7},   /* 第二行索引为1 */
            {8, 9, 10, 11}, /* 第三行索引为2 */
        }
        fmt.Println(erweiarr)
    
        //声明切片
        /*创建切片*/
        numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
        fmt.Printf("len=%d cap=%d slice=%v 
    ", len(numbers), cap(numbers), numbers)
        /*打印子切片从索引1(包含)到索引4(不包含)*/
        fmt.Println("numbers[1:4] ==", numbers[1:4])
        /*默认下限为0*/
        fmt.Println("numbers[:3] ==", numbers[:3])
        /*默认上限为len(s)*/
        fmt.Println("numbers[4:] ==", numbers[4:])
        /*打印子切片从索引0(包含)到索引2(不包含)*/
        number2 := numbers[:2]
        fmt.Println("number2 ==", number2)
        /*打印子切片从索引2(包含)到索引5(不包含)*/
        number3 := numbers[2:5]
        fmt.Println("number3 ==", number3)
    
        //定义数组
        arrr := [3]int{1, 2, 3}
        //根据数组截取切片
        nums1 := arrr[:] //数组转为切片
        nums2 := arrr[:]
        fmt.Println("arrr=", arrr)
        nums1[0] = 100
        fmt.Println("arrr=", arrr)
        nums2[1] = 200
        fmt.Println("arrr=", arrr)
        //Go语言len()和cap():获取切片长度和容量
        //切片的长度是切片中元素的数量。切片的容量是从创建切片的索引开始的底层数组中元素的数量。切片可以通过 len() 方法获取长度,可以通过 cap() 方法获取容量。数组计算 cap() 结果与 len() 相同,具体使用细节如下所示。
        arr0 := [...]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
        fmt.Println("cap(arr0)=", cap(arr0), arr0)
        //截取数组, 形成切片
        s01 := arr0[2:8]
        fmt.Printf("%T
    ", s01)
        fmt.Println("cap(s01)=", cap(s01), s01)
        s02 := arr0[4:7]
        fmt.Println("cap(s02)=", cap(s02), s02)
        //截取切片, 形成切片
        s03 := s01[3:9]
        fmt.Println("截取s01[3:9]后形成s03:", s03)
        s04 := s02[4:7]
        fmt.Println("截取s02[4:7]后形成s04:", s04)
        //切片是引用类型
        s04[0] = "x"
        fmt.Print(arr0, s01, s02, s03, s04)
    
        numberse := make([]int, 0, 20)
        numberse = append(numberse, 0)
        fmt.Println("numberse= ", numberse)
        /*同时添加多个元素*/
        numberse = append(numberse, 2, 3, 4, 5, 6, 7)
        fmt.Println("numberse= ", numberse)
        //追加一个切片
        s1 := []int{100, 200, 300, 400, 500, 600, 700}
        numberse = append(numberse, s1...)
        fmt.Println("numberse= ", numberse)
        //删除第一个元素
        numberse = numberse[1:]
        fmt.Println("numberse= ", numberse)
        //删除最后一个元素
        numberse = numberse[:len(numberse)-1]
        fmt.Println("删除最后一个元素= ", numberse)
        var country = map[string]string{
            "China":  "关联数组",
            "Japan":  "Tokyo",
            "India":  "New Delhi",
            "France": "Paris",
            "Italy":  "Rome",
        }
        fmt.Println(country)
        for k, v := range country {
            fmt.Println("国家", k, "首都", v)
        }
        //查看元素在集合中是否存在
        //可以通过 key 获取 map 中对应的 value 值。语法为:map[key]。
        // 当 key 不存在时,会得到该 value 值类型的默认值,
        // 比如 string 类型得到空字符串,int 类型得到 0,程序不会报错。
        // 所以可以通过value, ok := map[key]获知 key/value 是否存在。ok 是 bool 型,如果 ok 是 true,则该键值对存在,否则不存在。
        value, ok := country["England"]
        if ok {
            fmt.Println("首都:", value)
        } else {
            fmt.Println("首都信息未检索到!")
        }
        //或者
        if value, ok := country["Japan"]; ok {
            fmt.Println("首都 :", value)
        } else {
            fmt.Println("首都信息未检索到!")
        }
        //2. 根据key删除map中的某个元素
        if _, ok := country["Italy"]; ok {
            delete(country, "Italy")
        }
        fmt.Println(country)
        //判断是否包含子串
        fmt.Println(strings.Contains("seafood", "foo"))
        //将字符串 s 每个单词首字母大写返回
        fmt.Println(strings.Title("her royal highness"))
        //将字符串 s 转换成大写返回
        fmt.Println(strings.ToTitle("louD noises"))
        //按字典顺序比较a和b字符串大小
        fmt.Println(strings.Compare("abc", "bcd"))
        fmt.Println("abs" < "bcd")
        //判断s和t两个UTF-8字符串是否相等, 忽略大小写
        fmt.Println(strings.EqualFold("Go", "go"))
        //将字符串s重复count次返回
        fmt.Println("g" + strings.Repeat("o", 8) + "le")
        //将a中的所有字符连接成一个字符串, 使用字符串sep作为分隔符
        s := []string{"abc", "ABC", "123"}
        fmt.Println(strings.Join(s, ", "))
        fmt.Println(strings.Join(s, ";"))
        ss := "hel" + "lo,"
        ss += "world!"
        fmt.Println(ss) //输出 “hello, world!”
        // 创建一个整型切片,并赋值
        slice := []int{10, 20, 30, 40}
        // 迭代每一个元素,并显示其值
        for index, value := range slice {
            fmt.Printf("Index: %d Value: %d
    ", index, value)
        }
    
        // 声明一个二维整型切片并赋值
        erslice := [][]int{{10}, {100, 200}}
        fmt.Println("声明一个二维整型切片并赋值", erslice)
        // 为第一个切片追加值为 20 的元素
        erslice[0] = append(erslice[0], 30)
        fmt.Println("为第一个切片追加值为 30 的元素", erslice)
        erslice[1] = append(erslice[1], 50)
        fmt.Println("为第二个切片追加值为 50 的元素", erslice)
    
        //访问map中的每一个键值对
        scene := make(map[string]int)
        scene["route"] = 66
        scene["brazil"] = 4
        scene["china"] = 960
        for k, v := range scene {
            fmt.Println(k, v)
        }
        // 声明一个切片保存map数据
        var sceneList []string
        // 将map数据遍历复制到切片中
        for k := range scene {
            sceneList = append(sceneList, k)
        }
        // 对切片进行排序
        sort.Strings(sceneList)
        // 输出
        fmt.Println(sceneList)
    
        //在并发环境中使用的map
        //Go语言在 1.9 版本中提供了一种效率较高的并发安全的 sync.Map,sync.Map 和 map 不同,不是以语言原生形态提供,而是在 sync 包下的特殊结构。
        /*sync.Map 有以下特性:
        无须初始化,直接声明即可。
        sync.Map 不能使用 map 的方式进行取值和设置等操作,而是使用 sync.Map 的方法进行调用,Store 表示存储,Load 表示获取,Delete 表示删除。
        使用 Range 配合一个回调函数进行遍历操作,通过回调函数返回内部遍历出来的值,Range 参数中回调函数的返回值在需要继续迭代遍历时,返回 true,终止迭代遍历时,返回 false。*/
        var scenebf sync.Map
        // 将键值对保存到sync.Map
        scenebf.Store("greece", 97)
        scenebf.Store("london", 100)
        scenebf.Store("egypt", 200)
        // 从sync.Map中根据键取值
        fmt.Println(scenebf.Load("london"))
        // 根据键删除对应的键值对
        scenebf.Delete("london")
        // 遍历所有sync.Map中的键值对
        scenebf.Range(func(k, v interface{}) bool {
            fmt.Println("iterate:", k, v)
            return true
        })
    
        //list(列表)
        /*初始化列表
        list 的初始化有两种方法:分别是使用 New() 函数和 var 关键字声明,两种方法的初始化效果都是一致的。
        1) 通过 container/list 包的 New() 函数初始化 list
        变量名 := list.New()
        2) 通过 var 关键字声明初始化 list
        var 变量名 list.List
        给 list 添加元素:*/
        //双链表支持从队列前方或后方插入元素,分别对应的方法是 PushFront 和 PushBack
        l := list.New()
        l.PushBack("fist")
        l.PushFront(67)
        // 尾部添加
        l.PushBack("canon")
        // 头部添加
        l.PushFront(67)
        // 尾部添加后保存元素句柄
        element := l.PushBack("fist")
        // 在fist之后添加high
        l.InsertAfter("high", element)
        // 在fist之前添加noon
        l.InsertBefore("noon", element)
        // 使用
        l.Remove(element)
        //遍历列表——访问列表的每一个元素
        //遍历双链表需要配合 Front() 函数获取头元素,遍历时只要元素不为空就可以继续进行,每一次遍历都会调用元素的 Next() 函数,代码如下所示。
        for i := l.Front(); i != nil; i = i.Next() {
            fmt.Println("list:", i.Value)
        }
    
        //使用结构体类
        //顺序初始化,每个结构体中定义的成员必须都初始化
        var s11 Student = Student{1, "mike", 'm', 18, "bj"}
        fmt.Println("s1 = ", s11)
        //指定某个成员初始化,没有指定的成员默认自动赋值为0
        s22 := Student{name: "小明", addr: "bbb"}
        fmt.Println(s22)
        //使用里面的成员
        //定义一个结构体类普通变量
        var s12 Student
        // 操作成员,需要使用点 < .>运算符,就跟使用java中的 response类中的参数一样
        s12.id = 1
        s12.addr = "北京"
        s12.age = 28
        s12.name = "望京soho"
        s12.sex = 'm'
        fmt.Println("结构体类使用s12:", s12)
    
        //定义一个指针变量,用来保存s12的地址
        var p1 *Student
        p1 = &s12 //取地址s12
        //通过指针操作成员,p1.id 和 (*p1).id 完全等价,只能使用 . 运算符
        p1.id = 1
        (*p1).name = "aisi"
        p1.sex = 'm'
        p1.age = 18
        p1.addr = "soho"
        fmt.Println("p1=", p1)
        //通过new来实例化结构体类
        p2 := new(Student)
        p2.id = 1
        p2.name = "aisi"
        p2.sex = 'm'
        p2.age = 18
        p2.addr = "soho"
        fmt.Println("p2=", p2)
    
        //结构体使用函数传参
        s13 := Student{1, "mike", 'm', 18, "bj"}
        test01(s13)
        fmt.Println("s13:", s13)
    
        //计算价格函数调用
        jiagezong := jisuan(10, 2)
        fmt.Println("zongjia :", jiagezong)
        //Go 语言支持一个函数可以有多个返回值。我们来写个以矩形的长和宽为输入参数,计算并返回矩形面积和周长的函数rectProps。
        // 矩形的面积是长度和宽度的乘积, 周长是长度和宽度之和的两倍。即:
        area, perimeter := rectProps(10.8, 10.2)//如果不知道 := 前面返回类型,可以转中后面,ctrl alt +v 自己生成
        fmt.Printf("Area= %f Perimeter= %f", area, perimeter)
    
        /*空白符
        _ 在 Go 中被用作空白符,可以用作表示任何类型的任何值。我们继续以 rectProps 函数为例,该函数计算的是面积和周长。假使我们只需要计算面积,
        而并不关心周长的计算结果,该怎么调用这个函数呢?这时,空白符 _ 就上场了。*/
        area1, _ := rectProps(10.8, 10.2)//如果不知道 := 前面返回类型,可以转中后面,ctrl alt +v 自己生成
        fmt.Printf("Area1111= %f", area1)
    
        //Golang当中只有一种循环,就是for循环。没有while,更没有do while循环
        for i := 0; i < 10; i++ {
            fmt.Println(i)
        }
        //简写
        for i :=0; ;i++  {
            fmt.Println("简写方式:",i)
            if i>10{
                break
            }
        }
    
    }
    
    //写一个计算价格的函数,输入参数是单件商品的价格和商品的个数,两者的乘积为商品总价,作为函数的输出值。
    /*func 函数名(参数名 参数类型) returntype {
    // 函数体(具体实现的功能)
    }*/
    func jisuan(price int, num int) int {
        var totalPrice = price * num // 商品总价 = 商品单价 * 数量
        return totalPrice            // 返回总价; 返回值类型跟上面的返回值类型统一,就跟java的类差不多意思
    }
    
    //Go 语言支持一个函数可以有多个返回值
    func rectProps(length, width float64) (float64, float64) {
        var area = length * width
        var perimeter = (length + width) * 2
        return area, perimeter
    }
    //方式er  有多个返回值
    /*func rectProps(length, width float64)(area, perimeter float64) {
        area = length * width
        perimeter = (length + width) * 2
        return // 不需要明确指定返回值,默认返回 area, perimeter 的值
    }*/
    
    //结构体,相当于PHP的类,在main中使用
    type Student struct {
        id   int
        name string
        sex  byte
        age  int
        addr string
    }
    
    func test01(s Student) {
        s.id = 666
        fmt.Println("test01:", s)
    }
    
    func getData() (int, int) {
        return 100, 200
    }
    
    // 定义一个函数,遍历切片元素,对每个元素进行处理
    func visit(list []float64, f func(float64)) {
        for _, value := range list {
            f(value)
        }
    }
  • 相关阅读:
    Java new关键字的对象内存分配原理
    Android idleHandler
    Android Perffto工具
    Android Systrace工具
    Android TraceView工具
    Android App启动时间测量
    Android App启动分类
    Android线程的消息队列
    2018.2.28(延迟加载和缓存)
    2018.2.27(关联查询)
  • 原文地址:https://www.cnblogs.com/yszr/p/14373674.html
Copyright © 2011-2022 走看看