一、接口
//接口 package main ////定义接口 ////type 接口名 interface{ //// 方法 //// 方法 //// } // ////定义一个鸭子接口 //type Duck interface { // //speak(a int)(int) //speak 方法 // speak() // run() //} ////定义唐老鸭和普通鸭子两个结构体,他们的数据属性不尽相同 //type TLDuck struct { // name string // age int // wife string //} //type PTDuck struct { // name string // age int //} ////只要实现了Duck接口的所有方法,就叫实现了Duck接口 ////让唐老鸭实现Duck接口 //func (t *TLDuck)speak() { // fmt.Println("我是唐老鸭,我说人话") //} //func (t *TLDuck)run() { // fmt.Println("我是唐老鸭,我跟人一样走路") //} ////让普通鸭实现Duck接口 //func (t *PTDuck)speak() { // fmt.Println("我是普通鸭子,我嘎嘎") //} //func (t *PTDuck)run() { // fmt.Println("我是普通鸭,我歪歪扭扭走路") //} // //func main() { // tDuck:=&TLDuck{} // pDuck:=&PTDuck{} // speak(tDuck) // speak(pDuck) //} // ////func speak(a TLDuck) { //// a.speak() ////} ////func speak2(a PTDuck) { //// a.speak() ////} //func speak(a Duck) { // a.speak() //} //空接口(所有类型都继承了空接口) //type Empty interface { // //} //匿名空接口 //interface { // //} //func test6(a interface{}) { // fmt.Println(a) //} //func main() { // test6(1) // test6("lqz") // //} //类型断言 //定义一个鸭子接口 //package main // //import "fmt" // // //type Duck interface { // speak() // run() //} //type TLDuck struct { // name string // age int // wife string //} //type PTDuck struct { // name string // age int //} //func (t *TLDuck)speak() { // fmt.Println("我是唐老鸭,我说人话") //} //func (t *TLDuck)run() { // fmt.Println("我是唐老鸭,我跟人一样走路") //} //func (t *PTDuck)speak() { // fmt.Println("我是普通鸭子,我嘎嘎") //} //func (t *PTDuck)run() { // fmt.Println("我是普通鸭,我歪歪扭扭走路") //} //func main() { // tDuck:=&TLDuck{name:"唐老鸭"} // //pDuck:=&PTDuck{name:"周黑鸭"} // speak(tDuck) // //speak(pDuck) // //speak(1) // //speak("lqz") //} // //func speak(a interface{}) { // //s1:=a.(*TLDuck) //类型断言 // s1,err:=a.(*PTDuck) //类型断言 // //err 不是这个类型,返回false // if !err{ // fmt.Println("不是这个类型") // }else { // fmt.Println(s1.name) // } // //} //func speak(a interface{}) { // switch v:=a.(type) { // case *TLDuck: // fmt.Println( "我是tduck类型") // fmt.Println(v.name) // case *PTDuck: // fmt.Println("我是pduck类型") // case int: // fmt.Println("我是int类型") // default: // fmt.Println("我不知道你是什么类型") // } //} //package main // //import "fmt" // //type Describer interface { // Describe() //} //type Person struct { // name string // age int //} // //func (p Person) Describe() { // fmt.Printf("%s is %d years old", p.name, p.age) //} // //func findType(i interface{}) { // switch v := i.(type) { // case Describer: // v.Describe() // default: // fmt.Printf("unknown type\n") // } //} // //func main() { // findType("Naveen") // p := Person{ // name: "Naveen R", // age: 25, // } // findType(p) //} //package main // //func main() { // //a:=10 // const name = 10 // b:=[]int{} //}
接口二:
package main //import "fmt" // //type Describer interface { // Describe() //} //type Person struct { // name string // age int //} // //func (p Person) Describe() { // 使用值接受者实现 // fmt.Printf("%s is %d years old\n", p.name, p.age) //} // //type Address struct { // state string // country string //} // //func (a *Address) Describe() { // 使用指针接受者实现 // fmt.Printf("State %s Country %s", a.state, a.country) //} // //func main() { // var d1 Describer //定义了一个接口类型 // p1 := Person{"Sam", 25} //实例化得到p1 // d1 = p1 //把p1赋值给接口d1 // d1.Describe() // // p2 := Person{"James", 32} //实例化得到p2 // d1 = &p2 //把p2的地址取出来给了d1 // d1.Describe() // // var d2 Describer // a := Address{"Washington", "USA"} //实例化得到a对象,但是Address实现接口的时候,用的指针接收器 // // /* 如果下面一行取消注释会导致编译错误: // cannot use a (type Address) as type Describer // in assignment: Address does not implement // Describer (Describe method has pointer // receiver) // */ // //d2 = a // // d2 = &a // 这是合法的 // // 因为在第 22 行,Address 类型的指针实现了 Describer 接口 // d2.Describe() ////以后怎么用,基本上都用指针接收器实现接口 //// 在实例化得到对象时,直接取地址,进行传递 //// zz := &Address{"Washington", "USA"} //// d2=zz //} //实现多个接口,可以把值赋值给任意一个接口类型 //接口的嵌套 //type Animal interface { // speak() // run() //} //type Person interface { // Animal // eat() //} //type HPerson interface { // Animal // sleep() //} //type RealPerson struct { // name string //} // //func (a RealPerson)speak() { // //} //func (a RealPerson)run() { // //} //接口的空值 是nil type Animal interface { speak() run() } //func main() { // var a Animal // fmt.Println(a) // // a.speak() //出问题 //}
二、并发
//并发跟并行 package main import ( "fmt" "time" ) func sayHello() { fmt.Println("go hello") } func sayGood() { fmt.Println("good") } // func main() { fmt.Println("开始") go sayHello() go sayGood() time.Sleep(2*time.Second) }
三、信道
package main import "fmt" //import "fmt" // //func sayhello1(a chan int) { // fmt.Println("hello") // a<-1 //阻塞住 // //} //func main() { // //定义一个信道(信道只能运输int类型),空值是nil // //var a chan int // //fmt.Println(a) // //定义并初始化 // var a chan int=make(chan int) // //fmt.Println(a) // go sayhello1(a) // s:=<-a //读的时候,阻塞主 // fmt.Println(s) // //}
//信道:发送与接收默认是阻塞的
//func hello(done chan bool) { // fmt.Println("hello go routine is going to sleep") // time.Sleep(4 * time.Second) // fmt.Println("hello go routine awake and going to write to done") // done <- true //} //func main() { // done := make(chan bool) // fmt.Println("Main going to call hello go goroutine") // go hello(done) // <-done // fmt.Println("Main received data") //}
//案例 //func calcSquares(number int, squareop chan int) { // sum := 0 // for number != 0 { // digit := number % 10 // sum += digit * digit // number /= 10 // } // squareop <- sum //} // //func calcCubes(number int, cubeop chan int) { // sum := 0 // for number != 0 { // digit := number % 10 // sum += digit * digit * digit // number /= 10 // } // cubeop <- sum //} // //func main() { // number := 589 // sqrch := make(chan int) // cubech := make(chan int) // go calcSquares(number, sqrch) // go calcCubes(number, cubech) // squares, cubes := <-sqrch, <-cubech // fmt.Println("Final output", squares + cubes) //}
//死锁 //func main() { // ch := make(chan int) // ch <- 5 //读写操作默认都是阻塞的 // <-ch //}
//单向信道(只能读或者只能写) //func sendData(sendch chan<- int) { // sendch <- 10 //往里写没问题 // //} // //func main() { // sendch := make(chan int) //只写信道 定义成双向,传到函数中转成单向的,那就只能读或者只能写 // go sendData(sendch) // fmt.Println(<-sendch) //读的话有问题 //}
//关闭信道和使用 for range 遍历信道 //func producer(chnl chan int) { // for i := 0; i < 10; i++ { // chnl <- i // } // close(chnl) //} //func main() { // ch := make(chan int) // go producer(ch) // for { // v, ok := <-ch //如果信道关闭,取出的ok是false // if ok == false { // break // } // fmt.Println("Received ", v, ok) // } //} //func producer(chnl chan int) { // for i := 0; i < 10; i++ { // chnl <- i // } // close(chnl) //} //func main() { // ch := make(chan int) // go producer(ch) // for v := range ch { // 当信道关闭,for循环条件不符合,直接退出,如果用for rang循环,一定要g关闭信道 // fmt.Println("Received ",v) // } //} //重写示例 func digits(number int, dchnl chan int) { for number != 0 { digit := number % 10 dchnl <- digit number /= 10 } close(dchnl) } func calcSquares(number int, squareop chan int) { sum := 0 dch := make(chan int) go digits(number, dch) for digit := range dch { sum += digit * digit } squareop <- sum } func calcCubes(number int, cubeop chan int) { sum := 0 dch := make(chan int) go digits(number, dch) for digit := range dch { sum += digit * digit * digit } cubeop <- sum } func main() { number := 589 sqrch := make(chan int) cubech := make(chan int) go calcSquares(number, sqrch) go calcCubes(number, cubech) squares, cubes := <-sqrch, <-cubech fmt.Println("Final output", squares+cubes) }
四、缓冲信道
// 有缓冲的信道 package main import ( "fmt" "time" ) //func main() { // a:=make(chan int,3) //表示最多可以缓冲3个值 // a<-1 // a<-2 // a<-3 // fmt.Println(<-a) // <-a // <-a // //} //案例 //func write(ch chan int) { // for i := 0; i < 5; i++ { // ch <- i // fmt.Println("successfully wrote", i, "to ch") // } // close(ch) //} //func main() { // ch := make(chan int, 2) //大小为2的缓冲信道 // go write(ch) // time.Sleep(2 * time.Second) // for v := range ch { // fmt.Println("read value", v,"from ch") // time.Sleep(2 * time.Second) // // } //} //死锁 同无缓冲信道 //长度和容量 //func main() { // a:=make(chan int,5) // a<-1 // a<-2 // a<-3 // fmt.Println(len(a)) // fmt.Println(cap(a)) //} //WaitGroup 等待所有go协程执行完成 //import ( // "fmt" // "sync" // "time" //) //func process(i int, wg *sync.WaitGroup) { // fmt.Println("started Goroutine ", i) // time.Sleep(2 * time.Second) // fmt.Printf("Goroutine %d ended\n", i) // wg.Done() //} // //func main() { // no := 3 // var wg sync.WaitGroup //定义一个变量WaitGroup类型 // for i := 0; i < no; i++ { // wg.Add(1) // go process(i, &wg) // 需要传地址 // } // wg.Wait() //等待所有任务执行完成 // fmt.Println("All go routines finished executing") //} //等待所go协程执行完成 通过信道实现 func process(i int,a chan bool) { fmt.Println("started Goroutine ", i) time.Sleep(2 * time.Second) fmt.Printf("Goroutine %d ended\n", i) a<-true } func main() { no := 3 a:=make(chan bool) for i := 0; i < no; i++ { go process(i,a) } for i:=0;i<no;i++{ fmt.Println(<-a) } fmt.Println("All go routines finished executing") }