golang map中结构体元素是无法取地址的

map中的结构体元素是无法取地址的,即:map[string]struct类型,取&map[“tmp”]是错误的。会提示报错:

???cannot assign to struct field elem["count"].count in map。

原因为:map中的元素并不是一个变量,而是一个值。因此,我们不能对map的元素进行取址操作。

1.使用示例一:map对应的值为结构体类型的值

package main

import (
	"fmt"
	"time"
)

// Counter 代表计数器的类型。
type Counter struct {
	count int
}

var mapChan = make(chan map[string]Counter, 1)

func main() {
	syncChan := make(chan struct{}, 2)

	go func() { // 接收操作
		for {
			if elem, ok := <-mapChan; ok {
				counter := elem["count"] //传值
				counter.count++
				fmt.Printf("[receiver] The elem is: %v. Elem address: %p 
", elem, &elem)
				fmt.Printf("[receiver] The counter: %d.
", counter.count)

				/*
				map中的结构体元素是无法取地址的,即:map[string]struct类型,取&map["tmp"]是错误的.
   				使用下面的语句,会报提示语 cannot assign to struct field elem["count"].count in map.
				 */
				//elem["count"].count++
				//fmt.Printf("[receiver] The elem is: %v. Elem address: %p 
", elem, &elem)
				//fmt.Printf("[receiver] The counter: %d.
", elem["count"].count)
			} else {
				break
			}
		}
		fmt.Println("[receiver] Stopped.")
		syncChan <- struct{}{} // 发送同步通知
	}()

	go func() { // 发送操作
		countMap := map[string]Counter{
			"count": Counter{},
		}
		for i := 0; i < 5; i++ {
			mapChan <- countMap
			time.Sleep(time.Millisecond)
			fmt.Printf("[sender] The count map: %v. Count map address: %p 
", countMap, &countMap)
			fmt.Printf("[sender] The counter: %d.
", countMap["count"].count)
		}
		close(mapChan)
		syncChan <- struct{}{} // 发送同步通知
	}()

	<-syncChan //接收同步通知
	<-syncChan //接收同步通知
}

运行结果如下所示:

[receiver] The elem is: map[count:{0}]. Elem address: 0xc000078000
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc000078010
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc0000a0000
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc00000c040
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc000078020
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] Stopped.

2. 使用示例二:map对应的值为结构体类型的指针

package main

import (
	"fmt"
	"time"
)

// Counter 代表计数器的类型。
type Counter struct {
	count int
}


// 注意:map对应的值为地址(指针)
var mapChan = make(chan map[string]*Counter, 1)

func main() {
	syncChan := make(chan struct{}, 2)

	go func() { // 接收操作
		for {
			if elem, ok := <-mapChan; ok {
				counter := elem["count"] //传地址
				counter.count++
				fmt.Printf("[receiver] The elem is: %v.  Elem address: %p
", elem, &elem)
				fmt.Printf("[receiver] The counter: %d.
", counter.count)

				/*
				map中的元素是无法取地址的,即:map[string]struct类型,取&map["tmp"]是错误的.
   				使用下面的语句,会报提示语 cannot assign to struct field elem["count"].count in map.
				 */
				//elem["count"].count++
				//fmt.Printf("[receiver] The elem is: %v. Elem address: %p 
", elem, &elem)
				//fmt.Printf("[receiver] The counter: %d.
", elem["count"].count)
			} else {
				break
			}
		}
		fmt.Println("[receiver] Stopped.")
		syncChan <- struct{}{}
	}()

	go func() { // 发送操作
		countMap := map[string]*Counter{
			"count": &Counter{},
		}
		for i := 0; i < 5; i++ {
			mapChan <- countMap
			time.Sleep(time.Millisecond)
			fmt.Printf("[sender] The count map: %v. Count map address: %p 
", countMap, &countMap)
			fmt.Printf("[sender] The counter: %d.
", countMap["count"].count)
		}
		close(mapChan)
		syncChan <- struct{}{}
	}()

	<-syncChan
	<-syncChan
}

运行结果如下所示:

[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00008a000
[receiver] The counter: 1.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 1.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00008a010
[receiver] The counter: 2.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 2.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00000c010
[receiver] The counter: 3.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 3.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00000c018
[receiver] The counter: 4.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 4.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00000c020
[receiver] The counter: 5.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 5.
[receiver] Stopped.

3. 使用示例三:map对应的值为int类型

package main

import (
	"fmt"
	"time"
)

var mapChan = make(chan map[string]int, 1)

func main() {
	syncChan := make(chan struct{}, 2)

	go func() { // 接收操作
		for {
			if elem, ok := <-mapChan; ok { // 从通道中获取值
				elem["count"]++
				fmt.Printf("[receiver] The elem is: %v. Elem address is: %p 
", elem, &elem)
			} else {
				break
			}
		}
		fmt.Println("[receiver] Stopped.")
		syncChan <- struct{}{} // 发送同步通知
	}()

	go func() { // 发送操作
		countMap := make(map[string]int) // map为引用类型,发送和接收的元素为同一个值
		for i := 0; i < 5; i++ {
			countMap["count"]++
			mapChan <- countMap // 向通道中输入值
			time.Sleep(time.Millisecond)
			fmt.Printf("[sender] The count map: %v. Count map address: %p 
", countMap, &countMap)
		}
		close(mapChan) // 关闭通道
		syncChan <- struct{}{} // 发送同步通知
	}()


	<-syncChan //接收同步通知
	<-syncChan //接收同步通知
	fmt.Println(" map为引用类型,发送和接收的元素指向同一个值.")
}

运行结果如下所示:

[receiver] The elem is: map[count:2]. Elem address is: 0xc000078000
[sender] The count map: map[count:2]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:4]. Elem address is: 0xc000078010
[sender] The count map: map[count:4]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:6]. Elem address is: 0xc00000c040
[sender] The count map: map[count:6]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:8]. Elem address is: 0xc0000a4000
[sender] The count map: map[count:8]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:10]. Elem address is: 0xc000078020
[sender] The count map: map[count:10]. Count map address: 0xc00000c030
[receiver] Stopped.
 map为引用类型,发送和接收的元素指向同一个值.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值