一、接口

//接口
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")
}
01-03 14:53