Skip to content

maps: new standard library package based on x/exp/maps #57436

Closed

Description

@ianlancetaylor

In #47649 @rsc proposed a new maps package in the standard library based on discussion in #47330. After we settled on an API we added the experimental package golang.org/x/exp/maps.

We now have experience with this package in practice. pkg.go.dev reports that it is imported by 615 other packages. I propose that it is now time to move this package into the standard library for the 1.21 release.

Doing this doesn't mean that we can't add more functions to the standard library maps package later. Any such additions should be suggested in their own separate proposal. (There are some existing proposals that would move from x/exp/maps to maps: at least #54012, #54454, #57191).

The specific API that we will put into the standard library is as follows.

// Keys returns the keys of the map m.
// The keys will be in an indeterminate order.
func Keys[M ~map[K]V, K comparable, V any](m M) []K

// Values returns the values of the map m.
// The values will be in an indeterminate order.
func Values[M ~map[K]V, K comparable, V any](m M) []V

// Equal reports whether two maps contain the same key/value pairs.
// Values are compared using ==.
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool

// EqualFunc is like Equal, but compares values using eq.
// Keys are still compared with ==.
func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool

// Clone returns a copy of m.  This is a shallow clone:
// the new keys and values are set using ordinary assignment.
func Clone[M ~map[K]V, K comparable, V any](m M) M

// Copy copies all key/value pairs in src adding them to dst.
// When a key in src is already present in dst,
// the value in dst will be overwritten by the value associated
// with the key in src.
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2)

// DeleteFunc deletes any key/value pairs from m for which del returns true.
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool)

Activity

  1. added this to the Proposal milestone on Dec 22, 2022
  2. hherman1 commented on Dec 22, 2022

    @hherman1

    Isn’t Clear obsoleted by the new clear builtin?

  3. ianlancetaylor commented on Dec 22, 2022

    @ianlancetaylor
    ContributorAuthor

    Thanks. I think you're right. I've edited the proposal to remove Clear.

  4. iamemilio commented on Dec 22, 2022

    @iamemilio

    I would love to see either a new type sortedMap, or the option to implement sorting/searching of maps by value on put/delete. This is a builtin type in a handful of other popular programming languages, and since I don't see many people being willing to implement red/black trees on their own, they will have to implement their own linked hash map with a sorted slice, which is generally less efficient in space complexity.

  5. mooijtech commented on Dec 22, 2022

    @mooijtech

    @iamemilio Seems out of scope for this proposal.

    References:

  6. earthboundkid commented on Dec 23, 2022

    @earthboundkid
    Contributor

    A concern I've had with EqualFunc before is it compares length first, so you can't use it if you want to consider m1 and m2 the same if any keys missing from one or the other have zero values. E.g., these two maps might be considered equivalent for some applications:

    var m1 = map[string]int {
       "a": 0,
       "b": 0,
       "c": 0,
    }
    var m2 = map[string]int {
       "b": 0,
       "c": 0,
       "d": 0,
    }
    
    eq := true
    for k := range m1 {
    	if m1[k] != m2[k] {
    		eq = false
    	}
    }
    for k := range m2 {
    	if m1[k] != m2[k] {
    		eq = false
    	}
    }
    fmt.Println(eq) // true

    Maybe the solution is to add a looser but slower function with a name like Equivalent.

  7. leighmcculloch commented on Dec 26, 2022

    @leighmcculloch
  8. moved this to Incoming in Proposalson Jan 4, 2023
  9. rsc commented on Jan 4, 2023

    @rsc
    Contributor

    This proposal has been added to the active column of the proposals project
    and will now be reviewed at the weekly proposal review meetings.
    — rsc for the proposal review group

  10. moved this from Incoming to Active in Proposalson Jan 4, 2023
  11. rsc commented on Jan 11, 2023

    @rsc
    Contributor

    @carlmjohnson if you feel strongly about Equivalent being in the package that should be a separate proposal. It seems a little niche to me.

  12. rsc commented on Jan 18, 2023

    @rsc
    Contributor

    Given that we already reviewed this API before it went into x/exp, it is not surprising there's not much discussion here. The proposal is exactly x/exp/maps minus Clear.

    Does anyone object to accepting this proposal?

  13. 11 remaining items

  14. gopherbot commented on Feb 1, 2023

    @gopherbot
    Contributor

    Change https://go.dev/cl/464343 mentions this issue: maps: new package

  15. added a commit that references this issue on Feb 12, 2023
    1966f70
  16. gopherbot commented on May 27, 2023

    @gopherbot
    Contributor

    Change https://go.dev/cl/498602 mentions this issue: doc/go1.21: mention maps package

  17. modified the milestones: Backlog, Go1.21 on May 30, 2023
  18. added a commit that references this issue on May 30, 2023
  19. jdemeyer commented on Aug 28, 2023

    @jdemeyer

    Keys and Values were removed: #61538

  20. added 2 commits that reference this issue on Sep 7, 2023
    e5da746
    410ebbc
  21. removed this from Proposalson Feb 8, 2024
  22. locked and limited conversation to collaborators on Aug 27, 2024
  23. added a commit that references this issue on Sep 29, 2026
    a964876
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions