1、使用go语言变量

func testVariable() {
	// 定义一个变量
	var a string
	fmt.Println(a)

	var b = 10
	fmt.Println(b) // 10

	// 简化(省略var和类型,go会自动判断,类似python)
	c := 20
	fmt.Println(c)

	// 多个变量声明(可以不同类型)
	d, e := 30,"string"
	fmt.Println(d,e) // 30 string
}
// 备注:小写开头的默认是私有的,类似private;大写开头的默认是共有的,类型public

// 下划线【_】作用
	//空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。
	//_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。

2、定义常量

var g =100 // 定义在方法外的是全局变量(其它的文件也能访问)
func testConst() {
	//显式类型定义:
	const a string = "abc"
	//隐式类型定义:
	const b = "abc"

	//常量还可以用作枚举:
	const (
		Unknown = 0
		Female = 1
		Male = 2
	)
	fmt.Println(Female) // 1
}

3、方法定义

/* 定义一个普通的方法,2个int参数,1个int返回 */
func max(num1, num2 int) int {
	/* 定义局部变量 */
	var result int

	if (num1 > num2) {
		result = num1
	} else {
		result = num2
	}
	return result
}

/* 定义一个普通的方法 ,2个返回值*/
func swap(x, y string) (string, string) {
	return y, x
}

/* 给结构体添加一个方法,在方法名前面声明结构体*/
// 定义结构体
type Circle struct {
	radius float64
}
//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
	//c.radius 即为 Circle 类型对象中的属性
	return 3.14 * c.radius * c.radius
}
// 使用
func testMain() {
	var c1 Circle
	c1.radius = 10.00
	fmt.Println("圆的面积 = ", c1.getArea())
}
//备注:小写开头的默认是私有的,类似private;大写开头的默认是共有的,类型public

4、测试数组

func testArray() {
	var a [3]int             // 定义三个整数的数组
	fmt.Println(a[0])        // 打印第一个元素
	fmt.Println(a[len(a)-1]) // 打印最后一个元素

	// 在数组的定义中,如果在数组长度的位置出现“...”省略号,则表示数组的长度是根据初始化值的个数来计算,因此,上面数组 q 的定义可以简化为:
	q := [...]int{1, 2, 3}
	fmt.Printf("%T\n", q) // "[3]int"


	// 打印索引和元素
	for i, v := range a {
		fmt.Printf("%d %d\n", i, v)
	}

	// 仅打印元素(_代表不读取)
	for _, v := range a {
		fmt.Printf("%d\n", v)
	}
}

5、测试切片

func testSlice() {
	// 空的切片(int 类型)
	sliceInt := []int{}
	fmt.Println(sliceInt)

	// 空的切片(interface{}是一个空接口,可以代表任何类型)
	sliceObject := []interface{}{}
	sliceObjectValue := []interface{}{1,2,"str"}
	fmt.Println(sliceObject) // []
	fmt.Println(sliceObjectValue) // [1 2 str]
	sliceObject = append(sliceObject, "value1") // 添加元素
	fmt.Println(sliceObject) // [value1]

	fmt.Println(sliceObjectValue[:1]) // [1]
	fmt.Println(sliceObjectValue[:3]) // [1 2 str]
	fmt.Println(sliceObjectValue[2:]) // [str]

	// 删除第二个元素(一定要加上...),将sliceObjectValue[2:]...添加到切片sliceObjectValue[:1]中
	sliceObjectValue = append(sliceObjectValue[:1], sliceObjectValue[2:]...) // [1 str] (如果不加就会是:[1 [str]])
	fmt.Println(sliceObjectValue)
}

6、测试map

func testMap() {
	// 测试map
	testIntMap := make(map[string]int) // key:string类型 value:int类型
	testIntMap["key1"] = 1
	testIntMap["key2"] = 2
	fmt.Println("测试map============")
	fmt.Println(testIntMap)
	testAllTypeMap := make(map[string]interface{}) // interface{} 代表所有类型,空接口,所有类型都实现了这个接口
	testAllTypeMap["intKey"] = 1
	testAllTypeMap["stringKey"] = "stringValue"
	fmt.Println(testAllTypeMap)

	// 测试interface{}
	fmt.Println("测试interface{}============")
	var varInterface interface{}
	varInterface = "100"
	fmt.Println(varInterface)
	s := varInterface.(string) // 强转为string
	fmt.Println(s)
}

7、测试通道

func testChan()  {
	// 通道
	chSend := make(chan int)
	go func(a int) { // a:形参 ,匿名函数,运行自己的goroutine(开启一个并发匿名函数)
		fmt.Println(a)
		chSend <- 1
		chSend <- 2
	}(10) // 10 :实参

	test, ok := <-chSend
	fmt.Println(ok)
	test1 := <-chSend
	fmt.Println(test)
	fmt.Println(test1)
}

8、new 使用

func test_new()  {
	i := new(int)
	fmt.Println(*i) // 0

	circle := new(Circle) // 可以new一个结构体
	fmt.Println(circle) // &{0}
}

9、range使用

/* go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。
   在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。*/
func test_range(){
	var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
	pow = append(pow, 0)
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
}

10、并发

/* Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。
	goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。*/
func say(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}
func test_say() {
	go say("world")
	say("hello")
}
// 备注:通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

11、接口

type Phone interface {
	call()
}
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() {
	fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct {
}
func (iPhone IPhone) call() {
	fmt.Println("I am iPhone, I can call you!")
}
func test_interface() {
	var phone Phone

	phone = new(NokiaPhone)
	phone.call()

	phone = new(IPhone)
	phone.call()
}

12、错误处理

/* Go 语言通过内置的错误接口提供了非常简单的错误处理机制
error类型是一个内置接口类型

我们可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:*/
func Sqrt(f float64) (float64, error) {
	if f < 0 {
		return 0, errors.New("math: square root of negative number")
	}
	return f*f,nil
}
func test_error() {
	result, err:= Sqrt(-1)

	if err != nil {
		fmt.Println(result,err) // 0 math: square root of negative number
	}
}

/* error 和errors.New 定义说明*/
type error interface { // 内置接口
	Error() string
}
func New(text string) error {
	return &errorString{text} // 这个errorString接口体实现了error接口,所以可以返回error
}
type errorString struct { // 定义一个结构体
	s string
}
func (e *errorString) Error() string { // 给errorString接口体实现Error方法,所以返回这个结构体就可以用error接口接收
	return e.s
}

13、【defer、panic、recover】

https://www.jianshu.com/p/63e3d57f285f