本文主要介绍Go语言中struct,类似与JavaScript的构造函数,Java/Python的类,但是细品差异其实不小,故做此总结。文中如有描述不对或则不合理的地方,请各位大佬积极留言,我会每日及时查看并核查纠正。
同一个struct现象
- 只包含
可比较类型- 只包含
非指针类型,案例1 - 包含
指针类型,案例2
- 只包含
// 案例1
// Person 结构体
type Person struct {
Name string
Age int
}
func test0001() {
p1 := Person{
Name: "conk",
Age: 18,
}
p2 := Person{
Name: "conk",
Age: 18,
}
fmt.Println(p1 == p2) // true
}
// 案例2
// Animal 结构体
type Animal struct {
Name string
Area *string
}
func test0002() {
areaA1 := "shanghai"
areaA2 := "上海"
a1 := Animal{
Name: "dog",
Area: &areaA1,
}
a2 := Animal{
Name: "dog",
Area: &areaA2,
}
a3 := Animal{
Name: "dog",
Area: &areaA2,
}
fmt.Println(a1 == a2) // false
fmt.Println(a2 == a3) // true
}
- 包含
不可比较类型
// Lesson 结构体
type Lesson struct {
ID int
Items []int
}
func test0003() {
l1 := Lesson{
ID: 1,
Items: []int{1, 2, 3},
}
l2 := Lesson{
ID: 1,
Items: []int{1, 2, 3},
}
// 编译报错: invalid operation: l1 == l2 (struct containing []int cannot be compared)
// fmt.Println(l1 == l2)
fmt.Println(reflect.DeepEqual(l1, l2)) // true
}
不同struct现象
// Class 结构体
type Class struct {
ID int
Area *string
}
// Room 结构体
type Room struct {
ID int
Area *string
}
func test0004() {
areaC := "shanghai"
areaR := "shanghai"
c := Class{
ID: 1,
Area: &areaC,
}
r := Room{
ID: 1,
Area: &areaR,
}
// cannot use r (type Room) as type Class in assignment
// c = r
// invalid operation: c == r (mismatched types Class and Room)
// fmt.Println(c == r)
// 强制类型转换后可以进行比较
rToc := Class(r)
fmt.Println(c == rToc) // false
rS := Room{
ID: 1,
Area: &areaC,
}
rToRS := Class(rS)
fmt.Println(c == rToRS) // true
}
工作中偶尔碰到的奇葩代码
struct作为map的key,前提必须保证struct可比较
// Product 结构体
type Product struct {
Name string
stock int
}
// SKU 结构体
type SKU struct {
Name string
ProductIds []int
}
func test0005() {
p1 := Product{
Name: "大猫",
stock: 1000,
}
pm := map[Product]string {
p1: "非常好",
}
fmt.Printf("%+v\n", pm) // map[{Name:大猫 stock:1000}:非常好]
}
func test0006() {
s1 := SKU{
Name: "朗文库存",
ProductIds: []int{1, 2, 3},
}
// 编译报错 invalid map key type SKUgo
sm := map[SKU]string {
s1: "库存很足够",
}
}