/**
并发控制: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()
}