対処方法
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
type Struct struct {
XXX int
xxx int
}
func main() {
s1 := Struct{ 1, 1}
s2 := Struct{ 1, 2}
opt := cmpopts.IgnoreUnexported(Struct{}) // ここ大事
fmt.Println("Diff: ", cmp.Diff(s1, s2, opt))
}
もう少し詳しく
どうやらgo-cmp
は、プライベートな変数があるとパニックになってしまうらしい。
実はこのプライベートの取り扱い方でいくつかパターンが用意されている。
プライベート変数は一致しなくてよい場合
import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
...
opt := cmpopts.IgnoreUnexported(Struct{}) // 最初のものと一緒
fmt.Println("Diff: ", cmp.Diff(s1, s2, opt))
プライベート変数も一致していてほしい場合
import (
"github.com/google/go-cmp/cmp"
...
opt := cmp.AllowUnexported(Struct{}) // こちらはcmpoptsではないので注意
fmt.Println("Diff: ", cmp.Diff(s1, s2, opt))
指定した変数のみ無視してほしい場合
import (
"github.com/google/go-cmp/cmp"
...
// 変数名を文字列で指定, パブリック変数も指定可能
opt := cmpopts.IgnoreFields(Struct{}, "xxx")
fmt.Println("Diff: ", cmp.Diff(s1, s2, opt))
さらに詳しく
ここまでで解決できない方は恐らく、構造体が複数の層に分かれているかと思います。
今回は、各構造体のプライベート変数の一致を無視した場合の対処法を以下に示します。
各自のユースケースに合わせてご使用ください。
package main
import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
var (
ignoreOpts = cmpopts.IgnoreUnexported(
Car{},
Wheel{},
)
car1 = &Car {
speed: 2.0,
Wheels: []*Wheel{
&Wheel{
Size: 3.0,
hardness: 1.0,
},
&Wheel{
Size: 4.0,
hardness: 2.0,
},
&Wheel{
Size: 5.0,
hardness: 3.0,
},
&Wheel{
Size: 6.0,
hardness: 4.0,
},
},
}
car2 = &Car {
speed: 4.0,
Wheels: []*Wheel{
&Wheel{
Size: 3.0,
hardness: 4.0,
},
&Wheel{
Size: 4.0,
hardness: 3.0,
},
&Wheel{
Size: 5.0,
hardness: 2.0,
},
&Wheel{
Size: 6.0,
hardness: 1.0,
},
},
}
car3 = &Car {
speed: 2.0,
Wheels: []*Wheel{
&Wheel{
Size: 3.0,
hardness: 1.0,
},
&Wheel{
Size: 4.0,
hardness: 2.0,
},
&Wheel{
Size: 5.0,
hardness: 3.0,
},
},
}
)
type Car struct {
speed float64
Wheels []*Wheel
}
type Wheel struct {
Size float64
hardness float64
}
func CarDiff(left *Car, right *Car) string {
return cmp.Diff(left, right, ignoreOpts)
}
func main() {
println("car1 & car2\n", CarDiff(car1, car2))
println("car1 & car3\n", CarDiff(car1, car3))
}
その他
まとめて比較してくれる機能は大変便利ですが、使用する場合はテストの結果を比較するときか、簡単なコードを書くときくらいにしときましょう。