c++ map 修改value_golang的常见问题:结构体引用、类型比较、map修改排序

1、结构体的内部变量在别的包调用,要注意大小写

答:在struct中的属性,严格区分首字母大小写,大写为公有属性,别的包可以访问到,小写为私有,别的包访问不到。

例如:

package mainimport(   "fmt"   "reflect")type People struct{   Age int   Name string}func main(){   temp := People{Age:20,Name:"mark"}   fmt.Println(temp.Age)   fmt.Println(temp.Name)   s := reflect.ValueOf(&temp).Elem()   s.Field(0).SetInt(30)   fmt.Println(s)   fmt.Println(temp)}

在golang中,如果结构体的内部变量在别的包调用,会出现类似“implicit assignment of unexported field”的问题。

因为,在golang中,软件结构是以包为单位的,在同一个包内属于内部,不同包之间属于包间。

给外部包用的变量,必须首字母大写,否则就会出现上述问题。

同时,结构体内部的变量,如果不声明为首字母大写的变量,也会出现该问题。

2b2d60e8f366fffade74e91376904ddf.png

2、使用多层的map,为何报panic ,assignment to entry in nil map

答:多层的map,每一层都要初始化 make()

注意这种map的嵌套的形式,make只初始化了map[string]T部分(T为map[int]int),所以下面的赋值会出现错误:

test := make(map[string]map[int]int)test["go"][0] = 0 // error

正确的做法:

test := make(map[string]map[int]int)test["go"] = make(map[int]int)test["go"][0] = 0

一个常用的做法:

test := make(map[string]map[int]int)if test["go"] = nil {    test["go"] = make(map[int]int)}test["go"][0] = 0

3、判断字符串是否包含时,两个比较的参数都要是字符串类型

答:静态语言的类型都是要两种同样的类型才可以比。当不同类型的比较时,要先转换类型。

比如使用

//week是星期几,int类型week := int(time.Unix(time.Now().Unix(),0).Weekday())//week要转换成字符串类型strings.Contains(“1,2,3,4,5,6”, strconv.Itoa(week))

golang中字符串和各种int类型之间的相互转换方式:

string转成int:int, err := strconv.Atoi(string)string转成int64:int64, err := strconv.ParseInt(string, 10, 64)int转成string:string := strconv.Itoa(int)int64转成string:string := strconv.FormatInt(int64,10)
d93c63577c9b75fbad28dae1ac2d827c.png

4、Map的增删改,遍历和排序

map类型是常用的一种字典类型,struct结构体的遍历和排序类似map。

增删改:

在Go语言中,Map中的值是不可以修改的。

比如:

package maintype Student struct {    Name string    Id int}func main() {    s := make(map[string]Student)    s["chenchao"] = Student{        Name:"chenchao",        Id:111,    }    s["chenchao"].Id = 222}

上面的代码会编译失败,因为在go中 map中的赋值属于值copy,就是在赋值的时候是把Student的完全复制了一份,复制给了map。而在go语言中,是不允许将其修改的。

但是如果map的value为int,是可以修改的,因为修改map中的int属于赋值的操作。

如何在go语言中原地修改map中的value呢? 答案是:传指针!

package mainimport "fmt"type Student struct {    Name string    Id int}func main() {    s := make(map[string]*Student)    s["chenchao"] = &Student{        Name:"chenchao",        Id:111,    }    s["chenchao"].Id = 222    fmt.Println(s)}

在结构体比较大的时候,用指针效率会更好,因为不需要值copy

当然,如果map中的value为 *int指针类型,那么在赋值时不可以用&123,因为int为常量,不占内存,没有内存地址

使用 delete() 函数从 map 中删除键值对

其中 map 为要删除的 map 实例,键为要删除的 map 中键值对的键。

scene := make(map[string]int)// 准备map数据scene["route"] = 66scene["brazil"] = 4scene["china"] = 960delete(scene, "brazil")for k, v := range scene {    fmt.Println(k, v)}

清空 map 中的所有元素

Go语言中并没有为 map 提供任何清空所有元素的函数、方法,清空 map 的唯一办法就是重新 make 一个新的 map,不用担心垃圾回收的效率,Go语言中的并行垃圾回收效率比写一个清空函数要高效的多。

遍历:

遍历key-value

package mainimport (        "fmt")func main() {        var mymap map[string]string        mymap = map[string]string{"1a": "Very", "2b": "good", "3c": "day"}        for key,value := range mymap {                fmt.Println(key,":",value)        }}

多层遍历:

for keyA, valA := range mainMapA {for subKeyA, subValA := range valA {fmt.Printf("mapName=%sKey=%sValue=%s", keyA, subKeyA, subValA)}}

map字典按照键排序和按照值排序

字典按键排序

package mainimport ("fmt""sort")func main() {m := map[string]int32{"roy":   18,"kitty": 16,"hugo":  21,"tina":  35,"jason": 23,}lst := []string{}for k, _ := range m {lst = append(lst, k)}sort.Strings(lst) //排序字符串fmt.Println(lst)m1 := map[int]string{19: "roy",41: "kitty",32: "jason",23: "hugo",}lst1 := []int{}for k, _ := range m1 {lst1 = append(lst1, k)}sort.Ints(lst1)//排序int类型fmt.Println(lst1)}

通过结构体实现字典按值排序。

package mainimport ("fmt""sort")func main() {mapInfo := map[string]int32{"roy":18,"kitty":16,"hugo":21,"tina":35,"jason":23,}type peroson struct {Name stringAge int32}var lstPerson []perosonfor k, v := range mapInfo {lstPerson = append(lstPerson, peroson {k, v})}sort.Slice(lstPerson, func(i, j int) bool {return lstPerson[i].Age > lstPerson[j].Age  // 降序// return lstPerson[i].Age < lstPerson[j].Age  // 升序})fmt.Println(lstPerson)}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值