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

/**
并发控制:context的学习
*/
func context_test() {
	PrintStartSeperator("context_test")
	ctx, cancel := context.WithCancel(context.Background())

	go func(ctx context.Context) {
		for {
			//评估条件是否可以结束,如果没有条件能够评估下来,那么执行default
			select {
			case <-ctx.Done():
				fmt.Println("I am sub go func! I will quit!")
				return
			default:
				fmt.Println("i am sub go func! Let's sleep somewhile")
				time.Sleep(2 * time.Second)
			}
		}
	}(ctx)

	time.Sleep(4 * time.Second)
	fmt.Println("I am main func. I will quit!")
	//执行该函数的时候,下面的goroutine就能检测到并退出
	cancel()
	time.Sleep(3 * time.Second)
	fmt.Println("Everything is over!!")
	PrintEndSeperator()
}

type Animal interface {
	get_name() string
	set_name(string)
}

type Cat struct {
	name string
}

/**
set方法,此处为指针传递
*/
func (c *Cat) set_name(n string) {
	c.name = n
}

/**
get方法,此处为值传递
*/
func (c Cat) get_name() string {
	return c.name
}

type Dog struct {
	name string
}

/**
set方法,此处也为[值]传递
*/
func (d Dog) set_name(n string) {
	d.name = n
}

/**
get方法,此处为值传递
*/
func (d Dog) get_name() string {
	return d.name
}

//通用的打印函数
func print_animal_name(animal Animal) {
	fmt.Printf("My animal:%s\n", animal.get_name())
}

//通用的打印函数
func print_all_animals(animals []interface{}) {
	for _, ani := range animals {
		fmt.Print("ani: ")
		fmt.Println(ani)
	}
}

/**
关于interface更深一步的学习,关于函数中有指针传递和值传递的
*/
func interface_test2() {
	PrintStartSeperator("interface_test2")
	var cat = Cat{}
	cat.set_name("cat")
	//print_animal_name(cat)  这个是不行的,因为cat实现中有pointer receiver,所以这里必须用指针的方式
	print_animal_name(&cat)

	var dog = Dog{}
	dog.set_name("dog")
	print_animal_name(dog)  //和Cat形成对比,这里就是可以了,因为Dog没有pointer receiver的实现方式
	print_animal_name(&dog) //并且这种形式也是可以的,因为go会自动对pointer进行value的转换

	//var animals1 = []Animal{cat, dog} //这种是不可以的,因为cat有pointer receiver,但是Animal slice的接受值是value,所以这里会编译报错

	var animals = make([]interface{}, 2)
	animals[0] = cat
	animals[1] = dog
	print_all_animals(animals)

	PrintEndSeperator()
}

/*
select的学习
*/
func select_test() {
	PrintStartSeperator("select_test")
	ch1 := make(chan int)
	ch2 := make(chan int)

	func1 := func() {
		time.Sleep(time.Second * 2)
		ch1 <- 1
	}

	func2 := func() {
		time.Sleep(time.Second * 2)
		ch2 <- 1
	}

	go func1()
	go func2()

	time.Sleep(time.Second * 1)
	start := time.Now().Second()
	for {
		//对于select来讲,如果两个channel都有数据了,那么就会按顺序来case到,不需要下一次循环
		select {
		case <-ch1:
			fmt.Println("ch1 get the message")
		case <-ch2:
			fmt.Println("ch2 get the message")
		default:
			fmt.Println("i am default")
		}

		time.Sleep(time.Millisecond * 200)
		if time.Now().Second()-start > 4 {
			break
		}
	}
	PrintEndSeperator()
}

/**
time.ticker学习
*/
func ticker_test() {
	PrintStartSeperator("ticker_test")
	//每秒将会给channel发送一个消息
	ticker := time.NewTicker(time.Second)

	start := time.Now().Second()
	group := sync.WaitGroup{}
	group.Add(1)

	go func() {
		for {
			if time.Now().Second() - start > 4 {
				fmt.Println("ticker would exit!!!!")
				group.Done()
				return
			}

			select {
			case <-ticker.C:
				fmt.Println("ticker caught....")
			default:
				break
			}
		}
	}()

	//等待routine结束
	group.Wait()
	PrintEndSeperator()
}

posted @ 2020-07-06 17:01  不晓得叫什么  阅读(116)  评论(0编辑  收藏  举报