Goの構造体間で変換できる条件と比較できる条件について書きます。
構造体の変換について
Goの構造体の変換はフィールドの名・型・順番・数が一致していることが前提で変換することができます。例えば以下の様に, AとBでは構造体間の変換が可能です。
package main
import "fmt"
type A struct {
aa int
bb int
}
type B struct {
aa int
bb int
}
func main() {
a := A{
aa: 1,
bb: 2,
}
var b B
b = B(a) // 変換可能
fmt.Println(b) //=> {1 2}
}
逆に以下の様に、フィールド名が異なる・フィールドの型が異なる・フィールドの順番が異なる・フィールドの数が異なる、等の状態だと変換することができないです。
package main
type A struct {
aa int
bb int
}
type DifferentFieldName struct {
aa int
cc int
}
type DifferentFieldType struct {
aa uint
bb int
}
type DifferentFieldOrder struct {
bb int
aa int
}
type DifferentFieldNum struct {
aa int
bb int
cc int
}
func main() {
a := A{
aa: 1,
bb: 2,
}
var d DifferentFieldName
d = DifferentFieldName(a) // 変換不可: フィールド名が異なる
var d2 DifferentFieldType
d2 = DifferentFieldType(a) // 変換不可: フィールド名の型が異なる
var d3 DifferentFieldOrder
d3 = DifferentFieldOrder(a) // 変換不可: フィールドの定義順が異なる
var d4 DifferentFieldNum
d4 = DifferentFieldNum(a) // 変換不可: フィールドの数が異なる
}
構造体の比較について
Goの構造体が比較可能である条件は、同じ構造体の型であり、かつ全てのフィールドが比較可能である場合は比較できます。 フィールドが比較可能ということは、フィールドにsliceやmapなどが含まれていた場合は同じ構造体であっても比較することができません。
package main
import "fmt"
type A struct {
aa int
bb int
}
type B struct {
aa int
bb int
}
type C struct {
aa int
bb int
cc []int
}
func main() {
a := A{aa: 1, bb: 2}
a2 := A{aa: 1, bb: 2}
fmt.Println(a == a2) // => true(比較可能)
b := B{aa: 1, bb: 2}
fmt.Println(a == b) // 比較不可: 構造体の型が異なる
c := C{aa: 1, bb: 2, cc: []int{1, 2}}
c2 := C{aa: 1, bb: 2, cc: []int{1, 2}}
fmt.Println(c == c2) // 比較不可: 比較できないフィールドが含まれている
}
しかし、ある構造体と無名構造体の比較に関しては型が異なっていても、フィールドの名前・順番・型が同じであれば比較可能です。
package main
import "fmt"
type A struct {
aa int
bb int
}
func main() {
a := A{aa: 1, bb: 2}
b := struct {
aa int
bb int
}{
aa: 1,
bb: 2,
}
fmt.Println(a == b) //=> true
a2 := A(b) // 型変換も可能
}