Golang学习(用代码来学习) - 第三篇

type Books struct {
	title   string
	author  string
	subject string
	id      int
}

/**
结构体的学习
*/
func struct_test() {
	print_start_seperator("struct_test")
	//可以类似于c++那样直接通过值来初始化
	fmt.Println(Books{"thinking in go", "blucelee", "study", 0})

	//也可以使用key-value的方式,只指定部分,其他未指定的为默认值
	fmt.Println(Books{title: "thinking in java", author: "seanlee", id: 1})

	print_end_seperator()
}

/**
map学习
*/
func map_test() {
	print_start_seperator("map_test")

	var map1 map[string]string
	var map2 = make(map[string]string)

	//map1始终是个nil,通过make出来的map2不是nil
	if nil == map1 {
		fmt.Println("map2 is nil!!")
	}

	map2["one"] = "one"
	map2["two"] = "two"
	map2["three"] = "three"
	map2["four"] = "four"
	//如果是单个range,那么只有key
	for key := range map2 {
		fmt.Printf("1   key:%s  value:%s\n", key, map1[key])
	}

	for key, value := range map2 {
		fmt.Printf("2  key:%s  value:%s\n", key, value)
	}

	//判断一个key是否在map中
	value, ok := map2["five"]
	if ok {
		fmt.Println("five is in map!!! value:" + value)
	} else {
		fmt.Println("five is not in map!!!")
	}

	//删除一个key
	delete(map2, "three")
	for key, value := range map2 {
		fmt.Printf("After delation  key:%s  value:%s\n", key, value)
	}
	print_end_seperator()
}

//指针的学习
func pointer_test() {
	print_start_seperator("pointer_test")
	var p1 *int
	//与c中不同,go中的指针默认值为nil
	if (nil == p1) {
		fmt.Println("p1 is nil!!!")
	}

	//指针数组的用法
	const size = 5
	var arr [size]int = [size]int{5, 4, 3, 2, 1}
	var p_arr [size]*int

	for i := 0; i < size; i++ {
		p_arr[i] = &arr[i]
	}

	for i := 0; i < size; i++ {
		fmt.Printf("idx:%d addr:%p val:%d\n", i, p_arr[i], *p_arr[i])
	}

	//对于range,这里有个坑,range的实现使用了一个临时变量,因此如果取range的临时变量,那么地址将始终是一样的
	for idx, p := range &arr {
		//这里的p即为arr里面的值
		fmt.Printf("idx:%d p:%x\n", idx, p)
		//虽然说这里取p的地址从原则上来讲也是错误的。。
		p_arr[idx] = &p
	}

	//打印出来会发现所有的地址都是一样的,注意range的内部实现
	for idx, p := range p_arr {
		fmt.Printf("idx:%d p:%p\n", idx, p)
	}

	print_end_seperator()
}

/**
在go里面,只要实现了该函数,那么就默认实现了该接口
*/
type Phone interface {
	call() int
}

type NokiaPhone struct {
	desc string
}

func (phone *NokiaPhone) call() int {
	fmt.Println("I am nokia phone")
	return 0
}

type iPhone struct {
	desc string
}

func (phone *iPhone) call() int {
	fmt.Println("I am iphone!!")
	return 1
}

/**
如果interface里面没有任何函数,那么默认所有的struct都会继承interface,如果用interface作为
函数参数,那么说明该参数可以接受任意的参数
 */
func interface_para(inter interface{}){
	fmt.Printf("Interface with para. inter_type:%T\n", inter)
}


/**
interface的学习
*/
func interface_test() {
	print_start_seperator("interface_test")
	var phone1 Phone
	//注意,这里不是指针
	phone1 = new(NokiaPhone)

	var phone2 Phone
	phone2 = new(iPhone)

	phone1.call()
	phone2.call()

	//该函数可以接受任意类型的参数
	interface_para(1)
	interface_para("string")
	var sli = []int{1,2,3,4}
	interface_para(sli)
	var arr = [2]int{1,2}
	interface_para(arr)
	print_end_seperator()
}

type Person struct {
	name string
	age  int
	addr string
}

/**
专门用来处理错误的结构体
*/
type PersonError struct {
	err_msg string
}

/**
实现全局的error函数,来提供错误信息
*/
func (p *PersonError) Error() string {
	return p.err_msg
}

func (p *Person) checkAge() (bool, string) {
	if p.age < 10 {
		var err = PersonError{fmt.Sprintf("Invalid age[%d]\n", p.age)}
		return false, err.Error()
	}

	return true, ""
}

/*
错误处理学习: go里面提供了全局的Error的结构体来处理错误
*/
func error_handle_test() {
	print_start_seperator("error_handle_test")
	var p = Person{
		name: "BluceLee",
		age:  1,
		addr: "Chengdu",
	}

	if res, err := p.checkAge(); res {
		fmt.Println("This person info is ok!")
	} else {
		fmt.Printf("This person has error! err:%s\n", err)
	}

	defer func() {
		fmt.Println("first defer function in error_handle_test...")
	}()

	/**
	defer函数用来捕捉异常,如果没有异常的话,那么当函数执行完后会倒序执行
	*/
	defer func() {
		if err := recover(); nil != err {
			fmt.Printf("recover in error_handle_test. err:%s\n", err)
		} else {
			fmt.Println("There is no err info in error_handle_test defer function")
		}

		fmt.Println("second defer function in error_handle_test...")
	}()

	//recover panic 实验
	recover_panic_test()
	fmt.Println("outer after panic")

	defer func() {
		fmt.Println("third defer function in error_handle_test...")
	}()
	print_end_seperator()
}

/**
//recover panic 实验
*/
func recover_panic_test() {

	defer func() {
		fmt.Println("first defer function in inner func!")
	}()

	defer func() {
		fmt.Println("second defer function in inner func")
	}()

	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("in recover  in inner func. err:%s\n", err)
		} else {
			fmt.Println("There is no err info  in inner func")
		}
	}()

	panic("this is a panic  in inner func")

	fmt.Println("After panic function....  in inner func")

	defer func() {
		fmt.Println("After panic defer function...  in inner func")
	}()
}

posted @ 2020-06-19 18:18  不晓得叫什么  阅读(136)  评论(0编辑  收藏  举报