1、结构体声明
type 结构体名称 struct{
field type
field type
}
举例:
type Dog struct {
Name string
Age int
Color string
}
2、结构体使用
2.1 直接声明
var dog Dog
2.2 {}
type Dog struct {
Name string
Age int
Color string
}
func main() {
dog := Dog{"来福", 3, "白色"}
fmt.Printf("dog=%v\n", dog)
}
2.3 new()
type Dog struct {
Name string
Age int
Color string
}
func main() {
dog := new(Dog)
// dog是一个指针,因此标准的给字段赋值应该是(*dog).Name = "来福" (*dog).Age = 3 (*dog).Color = "白色"
// go设计者为了程序员使用方便,底层会对dog.Name = "来福"进行处理,会给dog加上取值运算(*dog).Name = "来福"
dog.Name = "来福" // 等价于(*dog).Name = "来福"
dog.Age = 3 // 等价于(*dog).Age = 3
dog.Color = "白色" // 等价于(*dog).Color = "白色"
fmt.Printf("dog=%v\n", *dog)
}
2.4 &
type Dog struct {
Name string
Age int
Color string
}
func main() {
dog := &Dog{"来福", 3, "白色"}
fmt.Printf("dog=%v\n", *dog)
}
2.5 创建struct实例指定字段值
type Person struct {
Name string
Age int
}
func main() {
person := Person{
Name: "Tom",
Age: 18,
}
personPor := &Person{
Name: "Jack",
Age: 20,
}
fmt.Println("person=", person)
fmt.Println("personPor=", *personPor)
}
第三种方式和第四种方式返回的是结构体指针,结构体指针访问字段的标准方式应该是:(*结构体指针).字段名,比如(*dog).Name = "来福"
3、方法的声明
func (recevier type) methodName(参数列表)(返回值列表){
方法体
return 返回值
}
参数列表,表示方法输入
recevier type:表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
recevier type:可以是结构体,也可以说是自定义类型。
recevier就是type类型的一个变量(实例)。
参数列表表示方法的输入
返回值列表,表示返回的值,可以是多个。
方法主体,表示为了实现某一功能代码块
return语句不是必须的
type Dog struct {
Name string
Age int
Color string
}
// 给Dog类型绑定一个方法
func (d Dog) Eat(food string) {
fmt.Printf("%v正在吃%v\n", d.Name, food)
}
func main() {
d := Dog{
Name: "小花",
Age: 3,
Color: "花色",
}
// 调用方法
d.Eat("骨头")
}
4、函数和方法的区别
调用方式不一样
函数的调用方式:函数名(实参列表)
方法的调用方式:变量.方法名(实参列表)
b. 对于普通函数,接收者是值类型时,不能将指针类型的数据直接传递
c. 对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法
type Person struct {
Name string
Age int
}
func (p Person) test() {
p.Name = "Merry"
}
func (p *Person) test01() {
p.Name = "Jack"
}
func main() {
person := Person{
Name: "Tom",
Age: 18,
}
person.test()
fmt.Println("name=", person.Name)
(&person).test() // 从形式上是传入地址,但本质任然是值拷贝
fmt.Println("name=", person.Name)
person.test01() // 等价于(&person).test01() 从形式上是传入值类型,但本质任然是地址拷贝
fmt.Println("name=", person.Name)
(&person).test01()
fmt.Println("name=", person.Name)
}
输出:
name= Tom name= Tom name= Jack name= Jack
不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和那个类型绑定的
如果是和值类绑定型,比如: (p Person) test(),则是值拷贝
如果是和地址类型绑定,比如:func (p *Person) test01(),则是地址拷贝
浙公网安备 33010602011771号