Golang 中 channel 类型断言分析

416 阅读1分钟
func main() {
    stopC := make(chan int)
    fmt.Printf("stopC: %p\n", stopC)
    i := interface{}(stopC)
    fmt.Printf("i: %p\n", i)
    c := i.(chan int)
    fmt.Printf("c: %p\n", c)
}

如果Channel中读出来的值类型是interface{}, 怎么对Channel进行类型断言呢?

上例中 stopC 的类型是 chan int, 用 interface{}(stopC) 构造了新的对象 i, 使用的是 := , 这个时候, i 和 stopC 还是指向的同一个对象吗?

看执行结果

stopC: 0xc000094060
i: 0xc000094060
c: 0xc000094060

显然, i 和 stopC 是指向的同一个对象 也就是说, 对 i 和 stopC 的操作会互相影响, 比如close(stopC), 那么读 i 的goroutine也会知道 i 已经 close了 同理, close(i), 读 stopC 的 goroutine 也会知道, 因为stopC和i本质上是同一个channel

由于i的类型是interface{}, 当通过断言, 把转换成chan int类型的c时, c和i还是指向同一个对象吗?

从上面的结果可知, i和c 确实都是指向同一个对象 同理, 操作i和c的效果是一样的

应用场景示例

// You can edit this code!
// Click here and start typing.
package main

import (
        "fmt"
        "time"
)

func main() {
        stopC := make(chan int)
        fmt.Printf("stopC: %p\n", stopC)
        i := interface{}(stopC)
        fmt.Printf("i: %p\n", i)
        c := i.(chan int)
        fmt.Printf("c: %p\n", c)

        go func() {
                v := <-c
                fmt.Println("v: ", v)
        }()

        go func() {
                v := <-c
                fmt.Println("v: ", v)
        }()

        go func() {
                v := <-c
                fmt.Println("v: ", v)
        }()

        go func() {
                ii := i.(chan int)
                ii <- 11
                time.Sleep(1)
                close(ii)
        }()

        go func() {
                stopC <- 22
        }()

        time.Sleep(2)
        fmt.Println("Hello, 世界")

}
stopC: 0xc00010c060
i: 0xc00010c060
c: 0xc00010c060
v:  22
v:  11v:  0Hello, 世界
Program exited.