使用make创建通道

huangapple go评论79阅读模式
英文:

Channel creation with make

问题

在Go语言中,你可以使用一个通道(channel)而不必使用make来创建它吗?还是说我总是需要使用make来创建通道?

在Go语言中,你必须使用make函数来创建一个通道。make函数会分配并初始化一个通道,并返回对该通道的引用。通道是一种特殊的数据类型,用于在Go协程之间进行通信和同步。因此,你不能直接声明一个通道变量而不使用make函数。

对于映射(maps)和切片(slices),情况是不同的。你可以使用字面量语法来创建映射和切片,而不必使用make函数。例如,你可以这样创建一个映射:

m := map[string]int{"a": 1, "b": 2, "c": 3}

或者创建一个切片:

s := []int{1, 2, 3, 4, 5}

使用字面量语法创建映射和切片会自动分配和初始化它们,并返回对它们的引用。因此,你不需要使用make函数来创建映射和切片。

英文:

Is there any case where I can use a channel without creating it with make, or should I always create it with make?

Does this also apply with maps and slices?

答案1

得分: 5

一般情况下,根据规范,应该使用make来创建通道:

>可以使用内置函数make来创建一个新的、初始化的通道值。

然而,在某些情况下,nil通道是有用的。规范中指出:

>nil通道永远不会准备好进行通信。

在某些情况下,这是有帮助的(参见这个答案,其中一个通道awaitRequest被故意设置为nil)。因此,从技术上讲,你可以“在不使用make创建通道”的情况下使用通道。

对于映射和切片,情况不同:

var m map[int]int
fmt.Println(m[1]) // 注意,你不能向nil映射添加元素
m1 := map[int]int{}
m1[1] = 2
m2 := map[int]int{1: 2}
fmt.Println(m2[0])
var s []int
fmt.Println(append(s, 1)) // nil切片是空的,但你可以追加元素
s1 := []int{}
fmt.Println(append(s1, 2))
s2 := []int{1}
fmt.Println(s2[0])

以上是一些替代方案。

英文:

> Is there any case where I can use a channel without creating it with make

In general channels should be created with make as per the spec:

>A new, initialized channel value can be made using the built-in function make

However there are cases where a nil channel is useful. The spec states that:

>A nil channel is never ready for communication.

This can he helpful in some situations (see this answer for an example where a channel, awaitRequest, is deliberately set to nil). So, technically, you can "use a channel without creating it with make".

> Does this also apply with maps and slices?

No - here are a few alternatives (playground):

var m map[int]int
fmt.Println(m[1]) // Note that you cannot add elements to a nil map
m1 := map[int]int{}
m1[1] = 2
m2 := map[int]int{1: 2}
fmt.Println(m2[0])
var s []int
fmt.Println(append(s, 1)) // Nil map is empty but you can append
s1 := []int{}
fmt.Println(append(s1, 2))
s2 := []int{1}
fmt.Println(s2[0])

huangapple
  • 本文由 发表于 2022年8月8日 06:04:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/73271366.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定