设为首页 加入收藏

TOP

Go语言备忘录:基本数据结构(三)
2017-09-30 13:21:03 】 浏览:1330
Tags:语言 备忘录 基本 数据结构
有序的获得映射的键值对,则需要先遍历出映射的键存到一个切片中,然后排序该切片,最后遍历该切片,按切片中元素的顺序去映射中取对应的值
  • delete(dict2,"srf") 从映射中删除指定的键值对;
  • 运行时会对映射的并发操作做出检测,对映射的操作只能同步进行(同一时刻只能有一个任务在操作映射),否则会导致进程崩溃。可用读写锁sync.RWMutex实现同步,避免读写操作同时进行:
  • func main() {
    	var lock sync.RWMutex
    	m:=make(map[string]int)
    
    	go func() {
    		for {
    			lock.Lock()
    			m["a"] += 1
    			lock.Unlock()  //不能用defer
    
    			time.Sleep(time.Microsecond)
    		}
    	}()
    
    	go func() {
    		for {
    			lock.RLock()
    			_ = m["b"]
    			lock.RUnlock()
    
    			time.Sleep(time.Microsecond)
    		}
    	}()
    
    	select {} //阻止进程退出
    }
    • 在函数间传递映射与传递切片一样(无须再次取地址),传递的只是映射本身的副本,而不会复制映射所引用的所有底层数据结构,对该映射副本所做的修改将会反映到所有对这个映射的引用。
    • 多维映射:即值为映射类型的映射。使用时应注意,作为值的映射也需要初始化后才能使用,如:
          var m1 = make(map[int]map[string]string)
          m1[13]= map[string]string{"srf":"yes"}
    • 判断两个map是否相等的函数:
    func equal(x, y map[string]int) bool {
        if len(x) != len(y) {
            return false
        }
        for k, xv := range x {
            if yv, ok := y[k]; !ok || yv != xv {
                return false
            }
        }
        return true
    }
    • 用map来表示字符串的集合set: 
    m:=make(map[string]bool)
    if !m["srf"] {
        m["srf"] = true
    }
    

     

    六、结构体

    • 结构体struct是一种复合类型,由多个不同类型的命名字段(field)系列打包而成;
    • 字段名必须唯一,可用“_”补位,支持使用自身的指针类型成员(这可以让我们创建递归的数据结构,比如链表和树结构等);
    type node struct{
        _ int
        id int `账号`
        next *node
    }
    • 结构体类型信息包括:字段名、字段标签、排列顺序,只有三者全部相同才可认为是同一类型;
    • 可按顺序初始化全部字段,但建议使用命名方式初始化部分或全部字段(可忽视字段的定义顺序,便于结构体成员顺序的修改、扩充);
    • 结构体的比较:只有当结构体的所有成员都是可比较的,那么该结构体才是可比较的
    • 可直接定义一个匿名的结构体类型,并赋值给一个变量,或用作字段的类型(匿名结构体字段无法用字面量形式直接初始化,需要“.”语法来初始化其成员)
    u := struct{
        name string
    }
    type file struct{
        name string
        attr struct{
            owner int
            perm int
        }
    }
    f := file{name:"test.dat"}
    f.attr.owner = 1
    f.attr.perm = 0755
    • 空结构:struct{},长度为0,不分配内存,它和其它所有“长度”为0的对象通常都指向runtime.zerobase变量(即它们都指向同一个变量);空结构类型经常作为通道元素的类型,用于事件通知(优点是不占内存);
    • 匿名字段(嵌入类型):即没有指定显式的名称,只有类型的字段:
      • 编译器将隐式地以类型名作为字段名称(不包含包名);
      • 外层的结构体不仅获得了匿名成员类型的所有成员,而且也获得了该类型全部的导出的方法;
      • 可直接引用嵌入类型字段的成员,但在以字面量语法初始化时须显式初始化它的整个结构;
      • 匿名字段的成员的数据类型必须是命名的类型或指向一个命名的类型的指针,不能是接口指针和多级指针;
      • 不能将基础类型和其指针类型同时作为匿名字段
      • 字段重名处理:优先使用外层字段(内层字段被遮蔽了,只能通过完全限定名来访问),对于多个相同层级的同名字段也必须通过完全限定名来访问,否则编译器无法确定目标;
    • 字段标签(tag):用来对字段进行描述的元数据,它虽然不属于数据成员,但却是类型信息的组成部分;在运行期,可用反射来获取字段的标签信息,它常被用作格式检验(如JSON)、数据库关系映射等;标准库reflect.StructTag提供了分/解析标签的功能;
    type user struct{
        name string `昵称`
        sex byte `性别`
    }
    func main(){
        u:=user{"TOM",1}
        v:=reflect.ValueOf(u)
        t:=v.Type()
        
        for i,n:=0,t.NumField();i<n;i++{
            fmt.Printf("%s: %v\n", t.Field(i).Tag, v.Field(i))
        }
    }
    • 不管结构体有多少个字段,它的内存总是一次性分配的,各字段在相邻的地址空间按定义顺序排列(包含嵌入字段的所有 成员)。对于引用类型、字符串、指针,结构内存中只包含其基本(头部)数据。
    • 结构体在分配内存时,会进行内存对齐处理(根据所有字段中最长的基础类型宽度为标准),唯一例外是编译器把空结构类型字段作为最后一个字段时的长度视为1来做对齐处理(避免越界)。
    • 内存对齐与硬件平台、以及访问效率有关(CPU在访问自然对齐的数据时需要的读周期更少,还可避免拼接数据)

     

    首页 上一页 1 2 3 下一页 尾页 3/3/3
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇推荐一款接口文档在线管理系统-Mi.. 下一篇gogland跨平台编译

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目