golang

Goで違うmapであることをテストする

Goにおけるmapは実体ではなく参照として扱われる。
故に、代入によっては実体はコピーされず参照だけがコピーされる。
よって、mapを複製する際は新しいmapを作ってそこに内容をコピーする必要がある。

しかし、これを素直にテストしようとすると困ったことになる。
というのも、 invalid operation: m2 == m1 (map can only be compared to nil) と怒られてしまうのだ。

https://play.golang.org/p/5e8dUMpU_ky

package main

func main() {
    m1 := map[int]int{}
    m2 := m1
    if m2 == m1 {
        println("m2 is same as m1")
    } else {
        println("m2 is different by m1")
    }

    m2 = map[int]int{}
    if m2 == m1 {
        println("m2 is same as m1")
    } else {
        println("m2 is different by m1")
    }
}

これでは困ってしまう。
reflect.ValueOf から Value.Pointer を呼び出すことでポインタを得ることができるのでこれを比較することで解決できそうだ。
https://golang.org/pkg/reflect/#Value.Pointer

https://play.golang.org/p/MrpS6SeBXIf

package main

import (
    "reflect"
)

func main() {
    m1 := map[int]int{}
    m2 := m1
    if reflect.ValueOf(m2).Pointer() == reflect.ValueOf(m1).Pointer() {
        println("m2 is same as m1")
    } else {
        println("m2 is different by m1")
    }

    m2 = map[int]int{}
    if reflect.ValueOf(m2).Pointer() == reflect.ValueOf(m1).Pointer() {
        println("m2 is same as m1")
    } else {
        println("m2 is different by m1")
    }
}

動いた!
もうちょっと良い方法ないもんかなー。