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是类型相关,一次只能传递一种类型

原文地址:https://www.cnblogs.com/yifan72/p/9151032.html