V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
choice4
V2EX  ›  Go 编程语言

Go map 有序

  •  
  •   choice4 · 2019-04-27 10:05:31 +08:00 via Android · 5596 次点击
    这是一个创建于 2035 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1.12.4,windows.


    Map 是不是有序了呢,我看的资料是 1.9.x 强调表示 map 被设计为无序,但我使用 map[int]string 时 ,map 总是有序的。
    17 条回复    2019-04-27 13:57:24 +08:00
    fighterlyt
        1
    fighterlyt  
       2019-04-27 10:11:03 +08:00
    不保证顺序,不代表有序,尤其是在不同版本之间,或者说不同数据之间。毕竟不可能为了无序,特意创建一些干扰
    fighterlyt
        2
    fighterlyt  
       2019-04-27 10:14:07 +08:00   ❤️ 1
    The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. 这是官方文档,说的很清楚,不保证,不描述,不确定
    choice4
        3
    choice4  
    OP
       2019-04-27 10:14:11 +08:00 via Android
    @fighterlyt key 顺序是 10,4,2,1,8 我测试总是有序,资料上是无序的(既没有大小排列,也没有按照保存顺序排列)。同时在我调整 key 值,整个 map 最后还是会按照 key 从小到大排列,就有了疑问。
    fighterlyt
        4
    fighterlyt  
       2019-04-27 10:15:26 +08:00
    @choice4 哪里资料上说无序了,程序员别看什么野鸡资料
    choice4
        5
    choice4  
    OP
       2019-04-27 10:18:29 +08:00 via Android
    @fighterlyt 谢谢大哥
    Zakun
        6
    Zakun  
       2019-04-27 10:19:47 +08:00 via Android
    无序,因为是动态扩展的,可能变化后顺序发生变化。
    fuxiaohei
        7
    fuxiaohei  
       2019-04-27 10:19:52 +08:00
    fmt.Print 在 1.12.4 做了顺序打印。你如果 range 一个一个打印,每次不同
    jadeity
        8
    jadeity  
       2019-04-27 10:21:24 +08:00   ❤️ 5
    reus
        9
    reus  
       2019-04-27 10:26:12 +08:00
    range 遍历是无序的,甚至小的 map 会刻意引入随机性,避免你依赖“遍历有序”这个偶然现象,因为语言规范没有规定 map 的遍历是有序的

    1.12 的打印是有序的,注意只是打印出来有序

    不要用“试验”,要看语言规范。你试验 1000 次是这样,不代表下一个版本也还是这样,不代表在其他操作系统上也是这样。
    heimeil
        10
    heimeil  
       2019-04-27 10:31:26 +08:00 via Android
    A map is an unordered group of elements of one type

    MapType = "map" "[" KeyType "]" ElementType .

    是指元素并不是像数组那样有序的存在一起,而是随机存储的
    kiwier
        11
    kiwier  
       2019-04-27 10:37:31 +08:00
    想有序用切片
    choice4
        12
    choice4  
    OP
       2019-04-27 11:43:49 +08:00
    @fuxiaohei
    @reus

    是的, 是因为 fmt.print 顺序打印, range 遍历确实无序。thx
    skadi
        13
    skadi  
       2019-04-27 12:04:40 +08:00
    无序
    loading
        14
    loading  
       2019-04-27 12:21:11 +08:00
    不保证有序,你看着想有序只是错觉。
    zhs227
        15
    zhs227  
       2019-04-27 13:51:06 +08:00
    从 1.12 开始,golang 工程师们为了方便码工们 debug,特意在直接打印输出时做了排序,但并不代表它是有序的
    zhs227
        16
    zhs227  
       2019-04-27 13:53:47 +08:00
    参考: https://golang.org/doc/go1.12
    1.12 的 release 包中关于 fmt 的修改:

    fmt
    Maps are now printed in key-sorted order to ease testing. The ordering rules are:

    When applicable, nil compares low
    ints, floats, and strings order by <
    NaN compares less than non-NaN floats
    bool compares false before true
    Complex compares real, then imaginary
    Pointers compare by machine address
    Channel values compare by machine address
    Structs compare each field in turn
    Arrays compare each element in turn
    Interface values compare first by reflect.Type describing the concrete type and then by concrete value as described in the previous rules.
    When printing maps, non-reflexive key values like NaN were previously displayed as <nil>. As of this release, the correct values are printed.
    EDDYCJY
        17
    EDDYCJY  
       2019-04-27 13:57:24 +08:00 via iPhone
    可以看下这篇文章 [为什么遍历 Go map 是无序的?],传送门: https://segmentfault.com/a/1190000018782278
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1207 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:16 · PVG 07:16 · LAX 15:16 · JFK 18:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.