您的位置 首页 golang

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

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

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

例如:

 package main

import(
   "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中,软件结构是以包为单位的,在同一个包内属于内部,不同包之间属于包间。

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

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

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)  

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

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

增删改:

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

比如:

 package main

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

}  

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

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

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

 package main

import "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"] = 66
scene["brazil"] = 4
scene["china"] = 960

delete(scene, "brazil")

for k, v := range scene {
    fmt.Println(k, v)
}  

清空 map 中的所有元素

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

遍历:

遍历key-value

 package main


import (
        "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=%s	Key=%s	Value=%s\n", keyA, subKeyA, subValA)
		}
	}  

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

字典按键排序

 package main

import (
	"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 main

import (
	"fmt"
	"sort"
)

func main() {
	mapInfo := map[string]int32{
		"roy":18,
		"kitty":16,
		"hugo":21,
		"tina":35,
		"jason":23,
	}

	type peroson struct {
		Name string
		Age int32
	}

	var lstPerson []peroson
	for 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)
}  

文章来源:智云一二三科技

文章标题:golang的常见问题:结构体引用、类型比较、map修改排序

文章地址:https://www.zhihuclub.com/86665.shtml

关于作者: 智云科技

热门文章

发表评论

您的电子邮箱地址不会被公开。

网站地图