• go笔记


    Go语言预定义了这些常量: true 、 false 和 iota 。

      iota 比较特殊,可以被认为是一个可被编译器修改的常量,在每一个 const 关键字出现时被  
      重置为0,然后在下一个 const 出现之前,每出现一次 iota ,其所代表的数字会自动增1

    Go语言内置以下这些基础类型:
     布尔类型: bool 。
     整型: int8 、 byte 、 int16 、 int 、 uint 、 uintptr 等。
     浮点类型: float32 、 float64 。

     复数类型: complex64 、 complex128 。
     字符串: string 。
     字符类型: rune 。
     错误类型: error 。
    此外,Go语言也支持以下这些复合类型:
     指针(pointer)
     数组(array)
     切片(slice)
     字典(map)
     通道(chan)
     结构体(struct)
     接口(interface)

    -------------------------------

    int 和 int32 在Go语言里被认为是两种不同的类型,编译器也不会帮你自动
    做类型转换

    var value2 int32
    value1 := 64 // value1将会被自动推导为int类型
    value2 = value1 // 编译错误

    两个不同类型的整型数不能直接比较,比如 int8 类型的数和 int 类型的数不能直接比较,但
    各种类型的整型变量都可以直接与字面常量(literal)进行比较

    fvalue2 := 12.0 // 如果不加小数点,fvalue2会被推导为整型而不是浮点型

    对于以上例子中类型被自动推导的 fvalue2 ,需要注意的是其类型将被自动设为 float64 ,
    而不管赋给它的数字是否是用32位长度表示的

    2. 浮点数比较
    因为浮点数不是一种精确的表达方式,所以像整型那样直接用 == 来判断两个浮点数是否相等
    是不可行的,这可能会导致不稳定的结果。
    下面是一种推荐的替代方案:
    import "math"
    // p为用户自定义的比较精度,比如0.00001
    func IsEqual(f1, f2, p float64) bool {
    return math.Fdim(f1, f2) < p
    }

    -----------------------

    字符串的内容可以用类似于数组下标的方式获取,但与数组不同,字符串的内容不能在初始
    化后被修改,比如以下的例子:
    str := "Hello world" // 字符串也支持声明时进行初始化的做法
    str[0] = 'X' // 编译错误

    在Go语言中支持两个字符类型,一个是 byte (实际上是 uint8 的别名)代表UTF-8字符串的单个字节的值;另一个是 rune ,代表单个Unicode字符

    并非一定要事先准备一个数组才能创建数组切片。Go语言提供的内置函数 make() 可以用于
    灵活地创建数组切片。下面的例子示范了直接创建数组切片的各种方法。
    创建一个初始元素个数为5的数组切片,元素初始值为0:
    mySlice1 := make([]int, 5)
    创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:
    mySlice2 := make([]int, 5, 10)
    直接创建并初始化包含5个元素的数组切片:
    mySlice3 := []int{1, 2, 3, 4, 5}
    当然,事实上还会有一个匿名数组被创建出来,只是不需要我们来操心而已。

    合理地设置存储能力的
    值,可以大幅降低数组切片内部重新分配内存和搬送内存块的频率,从而大大提高程序性能

    mySlice = append(mySlice, 1, 2, 3)
    函数 append() 的第二个参数其实是一个不定参数,我们可以按自己需求添加若干个元素,
    甚至直接将一个数组切片追加到另一个数组切片的末尾:
    mySlice2 := []int{8, 9, 10}
    // 给mySlice后面添加另一个数组切片
    mySlice = append(mySlice, mySlice2...)
    需要注意的是,我们在第二个参数 mySlice2 后面加了三个点,即一个省略号,如果没有这个省
    略号的话,会有编译错误,因为按 append() 的语义,从第二个参数起的所有参数都是待附加的
    元素。因为 mySlice 中的元素类型为 int ,所以直接传递 mySlice2 是行不通的。加上省略号相
    当于把 mySlice2 包含的所有元素打散后传入。
    上述调用等同于:
    mySlice = append(mySlice, 8, 9, 10)
    数组切片会自动处理存储空间不足的问题。如果追加的内容长度超过当前已分配的存储空间
    (即 cap() 调用返回的信息),数组切片会自动分配一块足够大的内存。

    5. 内容复制
    数组切片支持Go语言的另一个内置函数 copy() ,用于将内容从一个数组切片复制到另一个
    数组切片。如果加入的两个数组切片不一样大,就会按其中较小的那个数组切片的元素个数进行
    复制。下面的示例展示了 copy() 函数的行为:
    slice1 := []int{1, 2, 3, 4, 5}
    slice2 := []int{5, 4, 3}
    copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
    copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置

    2.4.流程控制

    关于条件语句,需要注意以下几点:
     条件语句不需要使用括号将条件包含起来 () ;
     无论语句体内有几条语句,花括号 {} 都是必须存在的;
     左花括号 { 必须与 if 或者 else 处于同一行;
     在 if 之后,条件语句之前,可以添加变量初始化语句,使用 ; 间隔;
     在有返回值的函数中,不允许将“最终的” return 语句包含在 if...else... 结构中,
    否则会编译失败:
    function ends without a return statement。
    失败的原因在于,Go编译器无法找到终止该函数的 return 语句。编译失败的案例如下:
    func example(x int) int {
    if x == 0 {
    return 5
    } else {
    return x
    }
    }

    在使用 switch 结构时,我们需要注意以下几点:
     左花括号 { 必须与 switch 处于同一行;
     条件表达式不限制为常量或者整数;
     单个 case 中,可以出现多个结果选项;
     与C语言等规则相反,Go语言不需要用 break 来明确退出一个 case ;
     只有在 case 中明确添加 fallthrough 关键字,才会继续执行紧跟的下一个 case ;
     可以不设定 switch 之后的条件表达式,在此种情况下,整个 switch 结构与多个
    if...else... 的逻辑作用等同

    Go语言的 for 循环同样支持 continue 和 break 来控制循环,但是它提供了一个更高级的
    break ,可以选择中断哪一个循环,如下例:

    小写字母开头的函数只在本包内可见,大写字母开头的函数才
    能被其他包使用。
    这个规则也适用于类型和变量的可见性

    func (file *File) Read(b []byte) (n int, err Error)
    同样,从上面的方法原型可以看到,我们还可以给返回值命名,就像函数的输入参数一样。
    返回值被命名之后,它们的值在函数开始的时候被自动初始化为空。在函数中执行不带任何参数
    的 return 语句时,会返回对应的返回值变量的值

    2.6错误处理

    3、面向对象编程

    在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,例如 bool 类型的零
    值为 false , int 类型的零值为0, string 类型的零值为空字符串

    参考文章: https://blog.csdn.net/feixiaoxing/article/details/38167559

    go struct 中小写开头是本包可使用,其他包不能使用,大写开头其他包都可以使用

    4、并发编程

    参考文章地址:https://www.cnblogs.com/zyf-zhaoyafei/p/5919421.html

    在一个函数调用前加上 go 关键字,这次调用就会在一个新的goroutine中并发执行。当被调用
    的函数返回时,这个goroutine也自动结束了。需要注意的是,如果这个函数有返回值,那么这个
    返回值会被丢弃

     不要通过共享内存来通信,而应该通过通信来共享内存

    channel 是进程内的通信方式,因此通过channel传递对象的过程和调用函数时的参数传递行为比较一直,比如传递指针。

    channel是类型相关,一次只能传递一种类型

  • 相关阅读:
    nginx反向代理
    遇到的好玩的mvc路由
    有意思的OWIN,附脱离iis的webapi
    nginx转发配置
    SQL 2016安装中遇到的问题
    3级级联 国家--城市
    box.css
    common.css
    节假日设置
    Order_Leave.aspx
  • 原文地址:https://www.cnblogs.com/yifan72/p/9151032.html
Copyright © 2020-2023  润新知