Go学习之——struct 进阶

Go学习之——struct 进阶

匿名字段

正经的结构定义

type person struct{
    
    
	name string
    age int
}

func main(){
    
    
    p1 = person{
    
    
        name: "内裤外穿的人",
        age: 10000,
    }
    fmt.Println("%v\n", p1)
    fmt.Println( p1.name)
    fmt.Println( p1.age)
    
}

匿名字段的结构定义

type person struct{
    
    
	string
    int
}

func main(){
    
    
    p1 = person{
    
    
        "内裤外穿的人",
        10000,
    }
    fmt.Println("%v\n", p1)
    fmt.Println( p1.string) //匿名字段 用类型名代替字段名来获取字段值
    fmt.Println( p1.int)   
}

匿名字段与具名字段同时使用

type person struct{
    
    
	name string
	string
    int
}

func main(){
    
    
    p1 := person{
    
    
        "内裤外穿的人",
        "超人",
        10000,
    }
    fmt.Printf("%v\n", p1)
    fmt.Println( p1.name)   
    fmt.Println( p1.string) //匿名字段 用类型名代替字段名来获取字段值
    fmt.Println( p1.int)   
}

匿名结构体定义的注意点:

  1. 匿名结构体,在使用的时候,要用类型名代替字段名来使用.
  2. 不能出现两个相同类型的字段
  3. 具名字段与匿名字段可以同时使用

结构体的方法

结构体的方法首先是一个函数,其特点是:

  1. 函数定义的时候,在函数名前加一个结构体的类型的参数
  2. 结构体类型的变量可以直接用.函数名的方法来调用
  3. 结构体变量是一个值类型的变量,如果在结构体方法里想要改变结构体字段的值,要使用结构体指针做为结构体方法的参数
type person struct {
    
    
	name string
	string
	int
}
// 这个方法,不能改变结构体的字段值
func (p person) speak() {
    
    
    p.int ++  //这个方法对原结构体是无效的
	fmt.Println("哈哈哈~~~")
}

func main() {
    
    
	p1 := person{
    
    
		"内裤外穿的人",
		"超人",
		10000,
	}
    fmt.Println(p1.int)
	p1.speak()
    fmt.Println(p1.int)
}

输出内容如下:

10000
哈哈哈~~~
10000

为了改变原结构体的字段值:

type person struct {
    
    
	name string
	string
	int
}
// 这个方法,不能改变结构体的字段值
func (p *person) speak() {
    
    
    p.int ++  //这个方法对原结构体是无效的
	fmt.Println("哈哈哈~~~")
}

func main() {
    
    
	p1 := person{
    
    
		"内裤外穿的人",
		"超人",
		10000,
	}
    fmt.Println(p1.int)
	p1.speak()
    fmt.Println(p1.int)
}

输出内容如下:

10000
哈哈哈~~~
10001

说明:

  1. 结构体方法本质是一个函数
  2. 结构体方法的调用就是结构体类型的变量.函数名
  3. 结构体方法如果要修改结构的属性值,要传入指针型变量
  4. 如果一个结构体有多个方法,这些方法最好统一结构:都用传值 或 都用传指针

结构体复合

这是正常的复合

type person struct{
    
    
	name string
    age int
    addr address
}

type address struct{
    
    
    city string
}

func main(){
    
    
    p1 := person{
    
    
        name: "张三",
        age: 20,
        addr: address{
    
    
            city:"浙江",
        },
    }
    fmt.Printf("%v\n", p1)
    fmt.Println(p1.addr.city)
}

这种方法,如果想要调用city的值,需要写的一长串.

如果能够像调用直接字段一样调用内层结构体的字段的话,会更加方便.

因此,改进如下

type person struct{
    
    
	name string
    age int
    address
}

type address struct{
    
    
    city string
}

func main(){
    
    
    p1 := person{
    
    
        name: "张三",
        age: 20,
        address: address{
    
      //匿名字段的初始用,直接用类型名作为字段用来赋值
            city:"浙江",
        },
    }
    fmt.Printf("%v\n", p1)
    fmt.Println(p1.address.city)  //匿名字段的常规调用方法
    fmt.Println(p1.city)  //优化后的可以直接调用内层结构体的方法
    
}

将内层结构体 设置为匿名字段,这样,外层结构体变量就可以直接 调用内层结构的字段,像调用自己的字段一样了.

type person struct {
    
    
	name string
	age  int
	city string
	address
}

type address struct {
    
    
	city string
}

func main() {
    
    
	p1 := person{
    
    
		name: "张三",
		age:  20,
		city: "北京",
		address: address{
    
    
			city: "浙江",
		},
	}
	fmt.Printf("%v\n", p1)
	fmt.Println(p1.address.city) //匿名字段的常规调用方法
	fmt.Println(p1.city)         //优化后的可以直接调用内层结构体的方法

}

如上代码输出:

{张三 20 北京 {浙江}}
浙江
北京

可以看到,直接调用city字段的时候,显示的是外层的结构体自带的字段.而不是内层结构体的字段值.

结论:

当外层结构体与内层结构体拥有相同的字段名时,直接调用字段名,获取到的是外层结构体的字段值.

即查找逻辑是由外而内的.

结构体的方法继承

package main

import "fmt"

type person struct{
    
    }
type student struct{
    
    }

func (p person) speak() {
    
    
	fmt.Println("会说话的人")
}
func main() {
    
    
	p1 := person{
    
    }
	p1.speak()
	s1 := student{
    
    }
	s1.speak()
}

编译的时候输出如下错误:

.\main.go:17:4: s1.speak undefined (type student has no field or method speak)

改进如下:

type person struct{
    
    }
type student struct {
    
    
	person   //匿名一个结构体字段.  这样,可以直接调用内层结构体的字段与方法.从而达成类似继承的效果
}

func (p person) speak() {
    
    
	fmt.Println("会说话的人")
}
func main() {
    
    
	p1 := person{
    
    }
	p1.speak()
	s1 := student{
    
    }
	s1.speak()
}

猜你喜欢

转载自blog.csdn.net/weixin_41810846/article/details/110452527