Go 结构体

29 阅读2分钟

结构体

定义结构体的格式:

type 结构体名 struct { }

package main

import "fmt"

// 结构体
type User struct {
	name string
	age  int
	sex  string
}

func main() {
	// 创建对象 (抽象 -> 具体个体)
	// 若定义了结构体对象, 但是不赋值, 默认都是这个结构体的零值 {"",0,""}
	var lisi User
	fmt.Println("user:", lisi)
	// 给对象赋值 xxx.属性 = 值
	lisi.name = "里斯"
	lisi.age = 19
	lisi.sex = "male"
	fmt.Println(lisi.name) // 访问属性与设置属性类似, 都是通过. 来获取

	// 创建对象的方式二
	user1 := User{} // 也通过短变量定义
	user1.name = "sam"

	// 创建对象的方式三 可以声明属性 也可以不声明属性(需要参数一一匹配)
	user2 := User{
		name: "ss",
		age:  19,
		sex:  "male",
	}
	fmt.Println(user2.name)
}

结构体指针

package main

import "fmt"

type User2 struct {
	name string
	age  int
	sex  string
}

func main() {
	user1 := User2{
		name: "Michael",
		age:  19,
		sex:  "male",
	}
	fmt.Println(user1)
	// 类型(结构体) 包.struct名
	fmt.Printf("%T %p\n", user1, &user1)
	// 结构体
	user2 := user1
	fmt.Printf("%T %p\n", user2, &user2) // 发现地址不一样 故结构体为值类型的
	// 使用指针能够结构值传递的问题
	var user_ptr *User2
	user_ptr = &user1 // 获取指针 *user_ptr 等价于 user1
	fmt.Println(user_ptr)
	fmt.Printf("%T %p\n", user_ptr, &user_ptr) // 发现地址不一样 故结构体为值类型的
	// 语法糖
	user_ptr.name = "ssss"
	fmt.Println(user1)
	// 通过 new 方法构建的对象, 返回指针
	// 这样创建的结构体是引用类型的 (指针嘛)
	user3 := new(User2)
	fmt.Println(user3)
	user3.name = "ann"
	user3.age = 19
	user3.sex = "female"
	fmt.Println(user3.name)
}

匿名结构体

匿名结构体: 没有名字的结构体 (此结构对于后面的oop来说十分关键)

package main

import "fmt"

// 匿名结构体: 没有名字的结构体
func main() {
	// 匿名结构体 (定义&赋值) 写在函数内部
	s2 := struct {
		name string
		age  int
	}{
		name: "sam",
		age:  19,
	}
	fmt.Println(s2.name, s2.age)
	// 匿名字段
	t1 := User3{
		string: "hahah",
		int:    0,
	}
	fmt.Println(t1.string, t1.int) // 打印匿名字段, 默认使用数据类型当做字段名称
}

// 匿名字段: 没有名字的字段, 属性类型 不能重复
type User3 struct {
	string
	int
}

结构体嵌套

package main

import "fmt"

// 结构体嵌套
type People struct {
	name    string
	age     int
	address Address
}
type Address struct {
	city, state string
}

// 通过结构体嵌套(拼接), 可以定义很多复杂的对象
func main() {
	var people = People{}
	people.name = "Amy"
	people.age = 19
	people.address = Address{
		city:  "guangzhou",
		state: "China",
	}
	fmt.Println(people.name, people.age, people.address)
	fmt.Println(people.address.city, people.address.state)
}

结构体导出

如果结构体名称首字母小写, 则结构体不会被导出, 别人不可访问

如果结构体名称首字母大写, 则结构体可被导出 (且只会导出大写字母开头的字段), 别人可以访问, 使用