zoukankan      html  css  js  c++  java
  • golang基础归纳

    1. hello-world

    package main
    import "fmt"
    
    func main(){
    fmt.Println("Hello world, Go Go!");
    fmt.Printf("type of Hello is %T
    ", "Hello")
    }

    package main--每一个Go文件都应该在开头进行package name的声明(注:只有可执行程序的包名为main)。包用于代码的封装与重用,这里包名为main。位于第一行。

    import "fmt"--导入fmt包,下面代码要使用。

    2. 注释

    单行注释://

    多行注释:/* */

    3. 空白符

    _在Go中被用作空白符,可以表示任何类型的任何值。

    4. 类型

    布尔:bool    // true,false

    字符串:string

    数字类型:int8,int16,int32,int64,int

    uint8,uint16,uint32,uint64,uint

    float32,float64

    complex64,complex128

    byte

    rune

    注:int,根据不同的底层平台,表示32或64位整型。除非对整形的大小有特定的需求,否则通常应该使用int表示整型。

    注:byte是uint8的别名,rune是int32的别名。

    注:+操作符用于拼接字符串。

    5. 类型转换

    Go有着非常严格的强类型特征,没有自动类型提升或类型转换,不允许将一种类型的变量赋值给另一种类型的变量。

    若要类型转换,需要显式类型装换,如int(f)等。

    i := 60.5
    j := 50
    sum := i + float64(j)

    自声明类型也不能和相同原类型混合使用:

        var str string = "Hello"
        type myString string
        var customName myString = "world"
        customName = str  // 不允许

    6. 格式说明符

    %T:打印变量的类型

    %v:打印变量的值

    %p:打印变量地址,本质等价与%x

    fmt.Printf("type of sum is %T
    ", sum)

    参考:https://studygolang.com/articles/2644 golang fmt格式占位符

    占位符     说明                           举例                   输出
    %v      相应值的默认格式。            Printf("%v", people)   {zhangsan},
    %+v     打印结构体时,会添加字段名     Printf("%+v", people)  {Name:zhangsan}
    %#v     相应值的Go语法表示            Printf("#v", people)   main.Human{Name:"zhangsan"}
    %T      相应值的类型的Go语法表示       Printf("%T", people)   main.Human
    %%      字面上的百分号,并非值的占位符  Printf("%%")            %
    布尔占位符
    占位符       说明                举例                     输出
    %t          true  false     Printf("%t", true)       true
    整数占位符
    占位符     说明                                  举例                       输出
    %b      二进制表示                             Printf("%b", 5)             101
    %c      相应Unicode码点所表示的字符              Printf("%c", 0x4E2D)        
    %d      十进制表示                             Printf("%d", 0x12)          18
    %o      八进制表示                             Printf("%d", 10)            12
    %q      单引号围绕的字符字面值,由Go语法安全地转义 Printf("%q", 0x4E2D)        '中'
    %x      十六进制表示,字母形式为小写 a-f         Printf("%x", 13)             d
    %X      十六进制表示,字母形式为大写 A-F         Printf("%x", 13)             D
    %U      Unicode格式:U+1234,等同于 "U+%04X"   Printf("%U", 0x4E2D)         U+4E2D
    浮点数和复数的组成部分(实部和虚部)
    占位符     说明                              举例            输出
    %b      无小数部分的,指数为二的幂的科学计数法,
             strconv.FormatFloat  'b' 转换格式一致。例如 -123456p-78
    %e      科学计数法,例如 -1234.456e+78        Printf("%e", 10.2)     1.020000e+01
    %E      科学计数法,例如 -1234.456E+78        Printf("%e", 10.2)     1.020000E+01
    %f      有小数点而无指数,例如 123.456        Printf("%f", 10.2)     10.200000
    %g      根据情况选择 %e  %f 以产生更紧凑的(无末尾的0)输出 Printf("%g", 10.20)   10.2
    %G      根据情况选择 %E  %f 以产生更紧凑的(无末尾的0)输出 Printf("%G", 10.20+2i) (10.2+2i)
    字符串与字节切片
    占位符     说明                              举例                           输出
    %s      输出字符串表示(string类型或[]byte)   Printf("%s", []byte("Go语言"))  Go语言
    %q      双引号围绕的字符串,由Go语法安全地转义  Printf("%q", "Go语言")         "Go语言"
    %x      十六进制,小写字母,每字节两个字符      Printf("%x", "golang")         676f6c616e67
    %X      十六进制,大写字母,每字节两个字符      Printf("%X", "golang")         676F6C616E67
    其它标记
    占位符      说明                             举例          输出
    +      总打印数值的正负号;对于%q(%+q)保证只输出ASCII编码的字符。 
                                               Printf("%+q", "中文")  "u4e2du6587"
    -      在右侧而非左侧填充空格(左对齐该区域)
    #      备用格式:为八进制添加前导 0(%#o)      Printf("%#U", '中')      U+4E2D
           为十六进制添加前导 0x(%#x)或 0X(%#X),为 %p(%#p)去掉前导 0x;
           如果可能的话,%q(%#q)会打印原始 (即反引号围绕的)字符串;
           如果是可打印字符,%U(%#U)会写出该字符的
           Unicode 编码形式(如字符 x 会被打印成 U+0078 'x')。
    ' '    (空格)为数值中省略的正负号留出空白(% d);
           以十六进制(% x, % X)打印字符串或切片时,在字节之间用空格隔开
    0      填充前导的0而非空格;对于数字,这会将填充移到正负号之后
    golang没有 '%u' 点位符,若整数为无符号类型,默认就会被打印成无符号的。

    7. sizeof

    Go的unsafe包提供一个Sizeof函数,该函数接收变量并返回它的字节大小。unsafe包应该小心使用,因为使用unsafe包可能带来可移植性问题。

    8. 变量

    var name type
    name = initalvalue
    var name type = initalvalue
    var name = initalvalue  // 类型推断
    var name1, name2 type = initalvalue1, initalvalue2
    var (
    name1 = initalvalue1
    name2 = initalvalue2
    )   // 一条语句声明不同类型变量
    name := initalvalue   // 简短声明用:=

    注:简短声明要求:=操作符左边的所有变量都要有初始值;要求:=操作符的左边至少有一个变量是尚未声明的。

    注意:go语言中定义的变量必须被用到,否则会报错。

    9. 常量

    const intZero int = 0

    双引号中的任何值都是Go中的字符串常量。

    无类型的常量有一个与它们相关联的默认类型,并且当且仅当一行代码需要时才提供它。在声明中 var name = "Sam"  name需要一个类型,它从字符串常量 Sam 的默认类型中获取。

    const a = 5
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println("intVar", intVar, "
    int32Var", int32Var, "
    float64Var", float64Var, "
    complex64Var", complex64Var)

    a 的值是 5 ,a 的语法是通用的(它可以代表一个浮点数、整数甚至是一个没有虚部的复数),因此可以将其分配给任何兼容的类型。这些常量的默认类型可以被认为是根据上下文在运行中生成的。 var intVar int = a 要求 a 是 int,所以它变成一个 int 常量。 var complex64Var complex64 = a 要求 a 是 complex64,因此它变成一个复数类型。

    连续常量或位可通过iota设置:

    const (
        Monday = itoa + 1 // 1
        Tuesday               // 2
        Wednesday         //  3   
    )
    
    const (
        Open = 1 << iota   // 0b00000001
        Close                     // 0b00000010
        Pending                 // 0b00000100
    )

    10. 函数

    func functionname(parametername1 type, parametername1 type) returntype {  
        // 函数体(具体实现的功能)
    }

    如果有连续若干个参数,它们的类型一致,那么我们无须一一罗列,只需在最后一个参数后添加该类型。

    从函数中可以返回一个命名值。一旦命名了返回值,可以认为这些值在函数第一行就被声明为变量了。

    func rectProps(length, width float64)(area, perimeter float64) {  
        area = length * width
        perimeter = (length + width) * 2
        return // 不需要明确指定返回值,默认返回 area, perimeter 的值
    }

    11. 包

    包用于组织Go源代码,提供了更好的可重用性和可读性。

    属于某一个包的源文件都应该放置于一个单独命名的文件夹里。按照 Go 的惯例,应该用包名命名该文件夹。

    导出名字

    在 Go 中,任何以大写字母开头的变量或者函数都是被导出的名字。其它包只能访问被导出的函数和变量。

    同一个包中,所有变量和函数都可调用,无论首字母是否大小写。

    init函数

    所有包都可以包含一个 init 函数。init 函数不应该有任何返回值类型和参数,在我们的代码中也不能显式地调用它。init 函数的形式如下:

    func init() {  
    }

    init 函数可用于执行初始化任务,也可用于在开始执行之前验证程序的正确性。

    包的初始化顺序

    首先初始化包级别(Package Level)的变量

    紧接着调用 init 函数。包可以有多个 init 函数(在一个文件或分布于多个文件中),它们按照编译器解析它们的顺序进行调用。

    如果一个包导入了另一个包,会先初始化被导入的包。尽管一个包可能会被导入多次,但是它只会被初始化一次。

    包前加点将包的命名空间导入

    import (
        . "github.com/smarystreets/goconvey/convey"
    )
    
    Convey()

    这样调用包的方法,不需要加包名。

    空白标识符

    导入了包,却不在代码中使用它,这在 Go 中是非法的。有两种处理方法:

    1)错误屏蔽器。在导入包后,用空白符引用包的变量。var _ = rectangle.Area

    2)导入包语句前使用空白符。_"geometry/rectangle"

    12. 条件判断

    if condition {  
    } else if condition {
    } else {
    }

    if statement; condition {  
    }

    注:else 语句应该在 if 语句的大括号 } 之后的同一行中。如果不是,编译器会不通过。

    13. 循环

    for是Go语言中唯一的循环语句。Go中没有while和do while循环。

    for initialisation; condition; post {  
    }

    其中initialization和post可以省略,而只使用condition

    for i <= 10 { //semicolons are ommitted and only condition is present
       fmt.Printf("%d ", i)
       i += 2
    }

    若condition也省略则表示无限循环。

    14. switch

    基础用法和C语言相似,包含switch…case…case…default。

    通过用逗号分隔,可以在一个 case 中包含多个表达式。 case 1,2, 3, 4, 5:

    switch中表达式可省略。如果省略表达式,则表示这个 switch 语句等同于 switch true,并且每个 case 表达式都被认定为有效,相应的代码块也会被执行。

        num := 75
        switch { // 表达式被省略了
        case num >= 0 && num <= 50:
            fmt.Println("num is greater than 0 and less than 50")
        case num >= 51 && num <= 100:
            fmt.Println("num is greater than 51 and less than 100")
        case num >= 101:
            fmt.Println("num is greater than 100")
        }

    在 Go 中,每执行完一个 case 后,会从 switch 语句中跳出来,不再做后续 case 的判断和执行。使用 fallthrough 语句可以在已经执行完成的 case 之后,把控制权转移到下一个 case 的执行代码中。

        switch num := number(); { // num is not a constant
        case num < 50:
            fmt.Printf("%d is lesser than 50
    ", num)
            fallthrough
        case num < 100:
            fmt.Printf("%d is lesser than 100
    ", num)
            fallthrough
        case num < 200:
            fmt.Printf("%d is lesser than 200", num)
        }

    fallthrough 语句应该是 case 子句的最后一个语句。如果它出现在了 case 语句的中间,编译器将会报错:fallthrough statement out of place

    字符串switch:switch varStr {case "foo", "bar", "zoo": .... }

    15. 数组

    Go语言不允许混合不同类型的元素。

    [n]Tn表示数组中元素的数量,T代表每个元素的类型。

    var a [3]int声明了一个长度为3的整型数组。数组中的所有元素都被自动赋值为数组类型的零值。

    数组的索引从0开始到length-1结束,长度用函数len()计算。

    a := [3]int{10, 11, 12} //简略声明

    a := [3]int{10}

    a := […]int{10, 11, 12} //忽略数组长度,用…代替

    数组的大小是类型的一部分,因此[5]int[20]int是不同类型。

    Go中的数组是值类型而不是引用类型。这意味着当数组赋值给一个新的变量时,该变量会得到一个原始数组的一个副本。对新变量的更改,不会影响原始数组。

    用==比较数组:相同维数且含有相同个数元素的数组才可以比较,每个元素都相同的才相等。

    for i, v := range arr {} // range方法遍历数组

    for _, v := range arr {} //忽略索引

        a := [3][2]string{
            {"lion", "tiger"},
            {"cat", "dog"},
            {"pigeon", "peacock"}, // this comma is necessary. The compiler will complain if you omit this comma
        }

    多维数组最后一组末尾要加逗号,否则根据Go语言的规则会自动插入分号。

    16. 切片

    切片是由数组简历的一种方便、灵活且功能强大的包装(wrapper)。切片本身不拥有任何数据,只是对现有数组的引用。对切片的所有修改都会反映到底层数组上。

    切片用[]T表示。

    a[start:end]创建一个从a数组索引start开始到end-1结束的切片。

    numa := [3]int{78, 79 ,80}
    nums1 := numa[:] // creates a slice which contains all elements of the array

    numa[:]缺少开始和结束值,开始和结束默认值分别是0len(numa)

    切片的长度是切片中的元素数。切片的容量是从创建切片索引开始的底层数组中元素数。

    func make[]Tlencap[]T 通过传递类型,长度和容量来创建切片。容量是可选参数, 默认值为切片长度。make 函数创建一个数组,并返回引用该数组的切片。

    make()创建的切片,默认元素值都是类型零值。之后用append()是在make()创建的切片之后添加元素,而非从slice[0]开始。

    func appends[]Tx ... T[]T用于向切片追加元素。

    如果切片由数组支持,并且数组本身的长度是固定的,那么切片如何具有动态长度,以及内部发生了什么?当新的元素被添加到切片时,会创建一个新的数组。现有数组的元素被复制到这个新数组中,并返回这个新数组的新切片引用。现在新切片的容量是旧切片的两倍。 

        var names []string //zero value of a slice is nil
        if names == nil {
            fmt.Println("slice is nil going to append")
            names = append(names, "John", "Sebastian", "Vinay")
            fmt.Println("names contents:",names)
        }

    切片类型的零值为 nil。一个 nil 切片的长度和容量为 0随后可用append()追加元素。

        veggies := []string{"potatoes", "tomatoes", "brinjal"}
        fruits := []string{"oranges", "apples"}
        food := append(veggies, fruits...)

    可以使用 ... 运算符将一个切片添加到另一个切片。

    值传递

    切片在内部可看作由一个结构体类型表示:

    type slice struct {  
        Length        int
        Capacity      int
        ZerothElement *byte
    }

    切片包含长度、容量和指向数组第零个元素的指针。当切片传递给函数时,即使它通过值传递,指针变量也将引用相同的底层数组。因此,当切片作为参数传递给函数时,函数内所做的更改也会在函数外可见。

    内存优化

    切片持有对底层数组的引用。只要切片在内存中,数组就不能被垃圾回收。这里需要重点注意的是,在切片引用时数组仍然存在内存中。

    一种解决方法是使用 copy 函数 func copy(dstsrc[]T)int 来生成一个切片的副本。这样我们可以使用新的切片,原始数组可以被垃圾回收。

    17. 可变参数的函数

    如果函数最后一个参数被记作 ...T ,这时函数可以接受任意个 类型参数作为最后一个参数。请注意只有函数的最后一个参数才允许是可变的。

    可变参数函数的工作原理是把可变参数转换为一个新的切片。 

    func find(num int, nums ...int) {
        for i, v := range nums {
            if v == num {
                fmt.Println(num, "found at index", i, "in", nums)
            }
        }
    }
    find(30, 10, 20, 30, 40)

    find(30)也是合法的,此时 nums 是一个长度和容量为 0 的 nil 切片。

    有一个可以直接将切片传入可变参数函数的语法糖,你可以在在切片后加上 ... 后缀。如果这样做,切片将直接传入函数,不再创建新的切片。

    find(89, nums…)  // true

    一个易错例程: 

    package main
    
    import (
        "fmt"
    )
    
    func change(s ...string) {
        s[0] = "Go"
        s = append(s, "playground")
        fmt.Println(s)
    }
    
    func main() {
        welcome := []string{"hello", "world"}
        change(welcome...)
        fmt.Println(welcome)
    }
    output:
    [Go world playground]
    [Go world]

    可变参数传递可变参数给内部函数怎样调用呢?本质上将可变参数理解为切片即可。

    package main
    import (
        "fmt"   
        "os"
        "os/exec"
        "strings"
    )
    
    func main(){
        sliceFunc(os.Args[1:]...)
    }
    
    func sliceFunc(cmd... string){
        fmt.Println(cmd)
        if len(cmd) == 0 { 
            fmt.Printf("Usage: %s args...
    ", os.Args[0])
            os.Exit(-1)
        }   
        fmt.Println(cmdFunc(cmd...))
    }
    
    func cmdFunc(cmd... string) string {
        fmt.Printf("cmd slice len: %d, value:%v
    ", len(cmd),  cmd)
        result, err := exec.Command(cmd[0], cmd[1:]...).Output()
        if err != nil {
            fmt.Println("Command failed:", err.Error())
        }   
    
    //  return string(result)  // with '
    '
        return strings.TrimSpace(string(result))
    }

    18. 键值对map

    map将键值关联的内置类型,通过相应的键可以获取到值。

    make(map[type of key]type of value):创建map

    map 的零值是 nil。如果你想添加元素到 nil map 中,会触发运行时 panic。因此 map 必须使用 make 函数初始化。

    var set map[int] bool                 ; set is nil

    set := map[int] bool {}               ; set is not nil,此方法初始化map也可行

    package main
    import "fmt"
    
    func main() {
        set := map[int]string {}
        if set != nil {
            fmt.Println(set)
        } else {
            set = make(map[int]string)
            set[0]="hello"
            fmt.Println(set)
    
        }
    
        var set1  map[int] interface {}
        if set1 != nil {
            fmt.Println(set1)
        } else {
            set1 = make(map[int]interface{})
            set1[0]="hello"
            set1[2]=100
            fmt.Println(set1)
        }
    }
    View Code
    $ go run map.go 
    map[]
    map[0:hello 2:100]

    键不一定只能是 string 类型。所有可比较的类型,如 booleanintergerfloatcomplexstring 等,都可以作为键。关于可比较的类型,如果你想了解更多,请访问 http://golang.org/ref/spec#Comparison_operators

    获取map中元素

    访问map中不存在的元素,map会返回该元素类型的零值。

    可通过如下语法判断key是否存在,如果oktrue,表示key存在,key对应的值就是value,反之key不存在。 

    value, ok := map[key]

    for range遍历map

        personSalary := map[string]int{
            "steve": 12000,
            "jamie": 15000,
        }
        personSalary["mike"] = 9000
        for key, value := range personSalary {
            fmt.Printf("personSalary[%s] = %d
    ", key, value)
        }

    注意,当使用 for range 遍历 map 时,不保证每次执行程序获取的元素顺序相同。

    delete(map, key):删除 map 中 key ,这个函数没有返回值。

    len(man):获取map长度。

    Map是引用类型,map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。

    map 之间不能使用 == 操作符判断,== 只能用来检查 map 是否为 nil判断两个 map 是否相等的方法是遍历比较两个 map 中的每个元素。map类型是不可比较的。

    19. 字符串

    string是数据类型,不是引用或指针类型,零值是空字符串(“”),而非nil。 if str == "" {}

    字符串是可比较的。if "wang" == varStr {}       switch varStr {case "foo", "bar", "zoo": .... }

    字符串就是一个字节切片。Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。

    len(s)返回字符串中字节的数量。

    UTF-8 编码中,一个代码点可能会占用超过一个字节的空间。需要使用rune

    rune Go 语言的内建类型,它也是 int32 的别称。在 Go 语言中,rune 表示一个代码点。代码点无论占用多少个字节,都可以用一个 rune 来表示。

    func printChars(s string) {
        runes := []rune(s)
        for i:= 0; i < len(runes); i++ {
            fmt.Printf("%c ",runes[i])
        }
    }
    // rune切片构造字符串
    runeSlice := []rune{0x0053, 0x0065, 0x00f1, 0x006f, 0x0072}

    func RuneCountInString(s string) (n int):获取字符串长度,需导入包unicode/utf8

    字符串是不可变得。为了修改字符串,可以把字符串转化为一个 rune 切片。然后这个切片可以进行任何想要的改变,然后再转化为一个字符串。 

    func mutate(s []rune) string {  
        s[0] = 'a' 
        return string(s)
    }
    fmt.Println(mutate([]rune(h)))

    20. 指针

    *T指向一个T类型的变量。

    指针的零值时nil 

    var a int = 25
    var b *int = &a
    
    *b++
    fmt.Printf("Type of b is %T
    ", b)
    fmt.Println("b is", b)
    output:
    Type of b is *int
    b is 0xc420072010
    a is 26 

    不要向函数传递数组的指针,而应该使用切片。

    对于数组:(*arr)[x]arr[x]等价,arr是数组指针。

    var arr *[3]int = [3]int{90, 100, 110}

    Go 并不支持其他语言(例如 C)中的指针运算,如b++,但支持*b++

    21. 结构体

    type Employee struct {
        firstName, lastName string
        age, salary         int
    }

    Employee被称为命名结构体。

        //creating structure using field names
        emp1 := Employee{
            firstName: "Sam",
            age:       25,
            salary:    500,
            lastName:  "Anderson",
        }
    
        //creating structure without using field names
        emp2 := Employee{"Thomas", "Paul", 29, 800}
    
        // creating structure pointer with zero value
        var pemp *Employee
        pemp = &Employee{}
     
        pemp2 := &Employee{}

     当定义好的结构体并没有被显式地初始化时,该结构体的字段将默认赋为零值。仅为某些字段指定初始值时,忽略的字段会赋值为零值。

    对于结构体指针, emp8.firstName 与 (*emp8).firstName等价。

    匿名字段的名称就默认为它的类型 

    type Person struct {  
        string
        int
    }
        var p1 Person
        p1.string = "naveen"
        p1.int = 50
        fmt.Println(p1)

    提升字段(Promoted Fields

    如果是结构体中有匿名的结构体类型字段,则该匿名结构体里的字段就称为提升字段。这是因为提升字段就像是属于外部结构体一样,可以用外部结构体直接访问。

    type Address struct {
        city, state string
    }
    type Person struct {
        name string
        age  int
        Address
    }
        var p Person
        p.name = "Naveen"
        p.age = 50
        p.Address = Address{
            city:  "Chicago",
            state: "Illinois",
        }
        fmt.Println("Name:", p.name)
        fmt.Println("Age:", p.age)
        fmt.Println("City:", p.city) //city is promoted field
        fmt.Println("State:", p.state) //state is promoted field

    导出结构体和字段

    如果结构体名称以大写字母开头,则它是其他包可以访问的导出类型(Exported Type)。同样,如果结构体里的字段首字母大写,它也能被其他包访问到。

    结构体相等性(Structs Equality

    结构体是值类型。如果它的每一个字段都是可比较的,则该结构体也是可比较的。如果两个结构体变量的对应字段相等,则这两个变量也是相等的如果结构体包含不可比较的字段,则结构体变量也不可比较。

    type name struct {  
        firstName string
        lastName string
    }
        name1 := name{"Steve", "Jobs"}
        name2 := name{"Steve", "Jobs"}
        if name1 == name2 {
            fmt.Println("name1 and name2 are equal")
        }

     22. defer

    含有defer语句的函数,会在该函数将要返回之前,调用另一个函数。

    在 Go 语言中,并非在调用延迟函数的时候才确定实参,而是当执行 defer 语句的时候,就会对延迟函数的实参进行求值。

    package main
    import (
            "fmt"
            "time"
    )
    
    func finished(v int){
            fmt.Printf("Finished something:%d
    ", v)
    }
    
    func process(v int){
            defer finished(v)
            fmt.Printf("Start processing...%d
    ", v)
            time.Sleep(2*time.Second)
            v = 3
            fmt.Printf("End processing...%d
    ", v)
    }
    
    func main(){
            process(5)
    }
    output:
    Start processing...5
    End processing...3
    Finished something:5

    当一个函数内多次调用 defer 时,Go 会把 defer 调用放入到一个栈中,随后按照后进先出(Last In First Out, LIFO)的顺序执行。

    23. 时间

    time包提供时间相关处理函数。

    now := time.Now()  time.Now().Day() time.Now().Minute() time.Now().Month()

    func Now() Time
    func (t Time) Nanosecond() int
    func (t Time) Second() int
    func (t Time) Minute() int
    func (t Time) Day() int
    func (t Time) Month() Month
    func (t Time) String() string
    const (
            Nanosecond  Duration = 1
            Microsecond          = 1000 * Nanosecond
            Millisecond          = 1000 * Microsecond
            Second               = 1000 * Millisecond
            Minute               = 60 * Second
            Hour                 = 60 * Minute
    )

    A Duration represents the elapsed time between two instants as an int64 nanosecond count. 

    type Duration int64

    24. strings和strconv

    strings

    strings.HasPrefix(s string, preffix string) bool:

    判断字符串s是否以prefix开头

    stirngs.HasSuffix(s string, suffix string) bool:

    判断字符串s是否以suffix结尾

    strings.Index(s string, str string) int:

    判断str在s中首次出现的位置,如果没有出现,则返回-1

    strings.LastIndex(s string,str string) int:

    判断str在s中最后出现的位置,如果没有出现,则返回-1

    strings.Replace(str string,old string,new string,n int):

    字符串替换

    strings.Count(str string,count int)string:

    字符串计数

    strings.Repeat(str string,count int) string:

    重复count次str

    strings.ToLower(str string)

    转换为小写

    strings.ToUpper(str string)string:

    转换为大写

    strings.TrimSpace(str string):

    去掉字符串首位空白字符

    strings.Trim(str string,cut string):

    去掉字符串首尾cut字符

    strings.TrimLeft(str string,cut string):

    去掉字符串首部cut字符

    strings.TrimRight(str string,cunt string):

    去掉字符串尾部cut字符

    strings.Field(str string):

    返回str空格分隔的所有子串的slice

    string.Split(str string,split string):

    返回str split分割的所有子串的slice

    strings.Join(s1 []string,sep string):

    用sep把s1中的所有元素连接起来

    strconv

    strconv.Itoa(i int):把一个整数转换成字符串

    strconv.Atoi (str string)(int,errror): 把一个字符串转换成整数

    25. 终端操作

    os.Stdin:标准输入

    os.Stdout:标准输出

    os.Stderr:标准错误输出

    26. 运算符

    &^按位清零

    将运算符左边的值按运算符右边值的位清零(右边为1清0,右边为0白痴原值)

    1 &^ 0 ---1      1&^1 -- 0       0 &^ 1 ---0        0 &^ 0 --- 0

    27. Context

    根Context:通过context.Background()创建

    子Context:context.WithCancel(parentContext)

    ctx, cancel := context.WitchCancel(context.Background())

    当前Context被取消后,基于它的context都会被取消

    接收取消通知 <- ctx.Done()

    参考:

    1. How to write Go Code  https://golang.google.cn/doc/code.html

    2. https://golang.google.cn/ 提供go在线测试环境和文档

    3. https://golang.google.cn/doc/ go相关文档

    4. https://golang.google.cn/pkg/ go标准库

    5.   https://godoc.org/ go实用库搜索

    6. go基础学习 coder python修行路

    7. Go 系列教程(Golang tutorial series) go语言中文网

    8.  https://github.com/geektime-geekbang/go_learning  极客时间学习

    9. Golang tutorial series  英文原版

  • 相关阅读:
    单片机模块化程序: 来看看加入环形队列的串口发送数据
    单片机模块化程序: 丢给你个环形队列玩玩
    单片机模块化程序: 你是否还是个小学生时代的串口发送数据
    单片机模块化程序: 关于串口接收处理数据
    单片机模块化程序: 看看是不是你想要的按键处理
    单片机模块化程序: 来看下我的程序架子吧
    ESA2GJK1DH1K升级篇: 升级STM32 预热: 单片机每隔一定时间 使用 http 获取天气
    ESA2GJK1DH1K升级篇: 升级STM32 预热: 单片机定时 使用 http 获取云端文本文件里面的内容,然后显示在液晶屏
    ESA2GJK1DH1K升级篇: 远程升级准备工作: 使用TCP客户端连接Web服务器实现http下载数据
    ESA2GJK1DH1K升级篇: 远程升级准备工作: 安装Web服务器
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/11025159.html
Copyright © 2011-2022 走看看