golang的struct{}类型channel

struct{}是结构体类型的代表;

struct{}{}是结构体的值,并且值为空的代表

之前看代码的时候发现有如下定义的channel,就觉得很诧异

var ch chan struct{}

这其中,struct{}是个什么鬼。

实际上struct{}就是一种普通数据类型,只是没有具体的值而已。

常用用法

通常struct{}类型channel的用法是使用同步,一般不需要往channel里面写数据,只有读等待,而读等待会在channel被关闭的时候返回。

package main

import (
    "time"
    "log"
)

var ch chan struct{} = make(chan struct{})

func foo() {

    log.Println("foo() 111");
    time.Sleep(5 * time.Second)
    log.Println("foo() 222");
    close(ch)
    log.Println("foo() 333");
}

func main() {

    log.Println("main() 111");
    go foo()
    log.Println("main() 222");
    <-ch
    log.Println("main() 333");
}

运行结果为

2018/04/12 06:46:33 main() 111
2018/04/12 06:46:33 main() 222
2018/04/12 06:46:33 foo() 111
2018/04/12 06:46:38 foo() 222
2018/04/12 06:46:38 foo() 333
2018/04/12 06:46:38 main() 333

在main函数里面ch读操作一直等待foo调用close(ch)才返回。

注意啊,channel对象一定要make出来才能使用。

往chann struct{}写入数据

另一个问题,我们能不能往struct{}类型的channel里面写数据呢,答案当然也是可以的。

package main

import (
    "time"
    "log"
)

var ch chan struct{} = make(chan struct{})

func foo() {
    ch <- struct{}{}
    log.Println("foo() 111");
    time.Sleep(5 * time.Second)
    log.Println("foo() 222");
    close(ch)
    log.Println("foo() 333");
}

func main() {

    log.Println("main() 111");
    go foo()
    log.Println("main() 222");
    <-ch
    log.Println("main() 333");
}

在foo()入口处给ch赋了一个值
注意写法是"struct{}{}",第一个"{}"对表示类型,第二个"{}"对表示一个类型对象实例。

运行结果:

2018/04/12 06:50:16 main() 111
2018/04/12 06:50:16 main() 222
2018/04/12 06:50:16 foo() 111
2018/04/12 06:50:16 main() 333

由于在foo()启动的时候往ch里面写入了一个对象,所以在main()函数里面不需要等待close(ch)就能拿到一个值,因此main()函数可以马上退出,不需要等到foo()的Sleep()完成。

带缓冲的chan struct{}数据读写

另外也可以定义带缓冲的channel

package main

import (
    "time"
    "log"
)

var ch chan struct{} = make(chan struct{}, 2)

func foo() {
    ch <- struct{}{}
    log.Println("foo() 000");
    ch <- struct{}{}
    log.Println("foo() 111");
    time.Sleep(5 * time.Second)
    log.Println("foo() 222");
    close(ch)
    log.Println("foo() 333");
}

func main() {
    var b struct{}

    log.Println("main() 111");
    go foo()
    log.Println("main() 222");
    a := <-ch
    log.Println("main() 333", a);
    b  = <-ch
    log.Println("main() 444", b);
    c := <-ch
    log.Println("main() 555", c);
}

运行结果为

2018/04/12 06:58:06 main() 111
2018/04/12 06:58:06 main() 222
2018/04/12 06:58:06 foo() 000
2018/04/12 06:58:06 foo() 111
2018/04/12 06:58:06 main() 333 {}
2018/04/12 06:58:06 main() 444 {}
2018/04/12 06:58:11 foo() 222
2018/04/12 06:58:11 foo() 333
2018/04/12 06:58:11 main() 555 {}

带两个缓冲大小的channel;
另外我们可以看到,其实也可以从channel里面读出数据来,但是这种数据显然没有实际意义。

作者:CodingCode
链接:https://www.jianshu.com/p/7f45d7989f3a
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/show58/p/12655396.html

时间: 2024-08-29 04:45:25

golang的struct{}类型channel的相关文章

[转]Golang之struct类型

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=22312037&id=3756923 一.struct        Go语言中,也有struct,定义与C语言类似,举例说明如下:        type person struct {            name string            age int        }        上面就声明了一个结构体person,包含两个字段.可以如下来使用这个str

Go语言struct{}类型的channel

在Go语言中,有一种特殊的struct{}类型的channel,它不能被写入任何数据,只有通过close()函数进行关闭操作,才能进行输出操作..struct类型的channel不占用任何内存!!! https://blog.csdn.net/qq_35976351/article/details/82026108 原文地址:https://www.cnblogs.com/longchang/p/12217763.html

学习Golang语言(6):类型--切片

学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Golang语言(5):类型--数组 学习Golang语言(6):类型--切片 在很多应用场景中,数组不能够满足我们的需求.在初始定义数组时,我们并不知道数组所需的长度.因此,我们需要一个大小可以动态变化的数组(动态数组) 在Go语言中,这种"动态数组"成为slice(切片). 但是实际上slic

sockaddr struct 类型重定义

windows.h和winsock2.h有类型重定义我是知道的,本来就一个库来说没问题,把winsock2放到windows.h前或先定义WIN32_LEAN_AND_MEAN都能解决问题但现的出了问题,自己写的一个库里要用到ws2tcpip,这个头文件第一个包含的头文件就是winsock2.h把它放到windows前,库是能成功编译了,但当我在一个wxWidgets中调用它时,又出现那个让人厌烦的错误 ““sockaddr”: “struct”类型重定义”明显是wxWidgets先包含了win

golang 函数作为类型

golang 函数作为类型 package main import "fmt" type A func(int, int) func (f A)Serve() { fmt.Println("serve2") } func serve(int,int) { fmt.Println("serve1") } func main() { a := A(serve) a(1,2) a.Serve() } type functinTyoe func(int)

GoLang获取struct的tag

GoLang获取struct的tag内容:beego的ORM中也通过tag来定义参数的. 获取tag的内容是利用反射包来实现的.示例代码能清楚的看懂! 1 package main 2 import ( 3 "fmt" 4 "reflect" // 这里引入reflect模块 5 ) 6 type User struct { 7 Name string "user name" //这引号里面的就是tag 8 Passwd string "

Golang之struct

1.用来定义复杂数据结构 2.struct里面可以包含多个字段(属性) 3.struct类型可以定义方法,注意和函数的区分. 4.struct类型是值类型 5.struct类型可以嵌套 6.Go语言没有class类型,只有struct类型 package main import "fmt" //声明结构体 type Student struct { Name string Age int Score int } func main() { //struct字段访问,使用“点”访问 va

C语言复杂struct类型get或者set字段的简化方法

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } span.s1 { font: 12.0px "Helvetica Neue" } 今天学习librdkafka的conf配置相关的代码,学到了一个C语言代码编写的技巧.作者真的是把C语言用得出神入化. 我们平时编写C语言代码,经常会用struct类型来模拟面向对象中的class.比如我实现了下面

golang中Any类型使用及空接口中类型查询

golang中Any类型使用及类型查询1.Any类型GO语言中任何对象实例都满足空接口interface{},空接口可以接口任何值var v1 interface{} = 1 var v2 interface{} = "abc" var v3 interface{} = 2.345var v4 interface{} = make(map[..]...).... 2.1 关于空接口的类型查询方式一,使用ok package main import "fmt" //空