Golang基础篇-struct

246 阅读2分钟

本文主要介绍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作为mapkey,前提必须保证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: "库存很足够",
	}
}