Channel 的声明

未匹配的标注

小白表示大概可能或许应该理解了什么是 Channel.

那么接下来我们来看看如何声明 Channel.

后文中为了便于表达, 我们使用信道来代替单词 channel.

在 Go 语言中, 提供的信道原语是 chan.

声明时 chan 后要紧跟数据类型, 表示该信道中可以承载的数据类型是什么.

如下:

// 声明一个信道变量 ch1, 其内可以承载 int 类型的数据
var ch1 chan int

// 声明一个信道变量 ch2, 其内可以承载 string 类型的数据
var ch2 chan string

同时顺带提一下, 信道通常在多个协程中读写, 所以按照读写区分, 还可以细分为:

  • 只读信道
  • 只写信道
  • 读写信道

声明分别如下:

// 只读信道
var readonlyChannel <-chan int

// 只写信道
var writeonlyChannel chan<- int

// 读写信道
var readWriteChannel chan int

在声明信道类型时

  • <-chan 箭头向外表示只读
  • chan<- 箭头向内表示只写
  • chan 没有箭头表示读写都可行

好了, 按照一般变量的方式信道是不是声明好了呢?

我们来测试下对声明的信道变量进行操作

// channel_test.go
// test ReadWriteChannel
func TestReadWriteChannel(t *testing.T) {
    var readWriteChannel chan int
    t.Logf("readWriteChannel type is %T", readWriteChannel)
    t.Log(readWriteChannel)
}

执行测试

go test .

不出意外的话, 输入如下

=== RUN   TestReadWriteChannel
--- PASS: TestReadWriteChannel (0.00s)
    channel_test.go:43: readWriteChannel type is chan int
    channel_test.go:44: <nil>
PASS

输出了信道的类型, 和我们声明的类型是一致的. 而信道变量的零值为 nil.

但是这样声明的信道变量并没有什么用, 实际应用中我们通过 make 给信道类型的分配内存空间.

我们来个测试对比看下

// channel_test.go
func TestChannel(t *testing.T) {
    var ch1 chan int
    t.Logf("ch1 type is %T", ch1)
    t.Log(&ch1)
    t.Log(ch1)

    //
    ch2 := make(chan int)
    t.Logf("ch2 type is %T", ch2)
    t.Log(&ch2)
    t.Log(ch2)
}

不出意外的话, 输出如下

=== RUN   TestChannel
--- PASS: TestChannel (0.00s)
    channel_test.go:56: ch1 type is chan int
    channel_test.go:57: 0xc000006038
    channel_test.go:58: <nil>
    channel_test.go:62: ch2 type is chan int
    channel_test.go:63: 0xc000006040
    channel_test.go:64: 0xc0000103c0
PASS

可以看到普通方式声明的信道变量与通过 make 函数声明的信道变量在初始值上是有区别的.

使用 make 函数声明的信道变量格外分配了内存空间.

这里暂时请记住, 使用 make 函数来声明信道变量.

小白表示记住 ch := make(chan int) 问题不大.

但是有什么用嘛? 然后呢?

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
taadis
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~