go 结构体

go结构体

结构体定义

结构体是go通过自定义的方式而形成的一种类型,很像是js中的对象,可以由一个或者是多个任意类型集合起来构成的实体

结构体中的成员不再称为“属性”,而是称为“字段”

  1. 字段名必须是唯一的
  2. 字段拥有自己的类型和值
  3. 字段的类型也可以是结构体,也可以是当前所在的结构体的类型

使用type关键字可以讲各种基本类型定义为一个结构体类型

type 结构体名 struct{
    字段1 字段1类型
    字段2 字段2类型
}
type struct1 struct{
    X int
    Y int
}
type struct2 struct{
    X,Y int
}

struct1和struct2所表示的含义是相同的

struct实例化

结构体只是一种对内存布局的描述,只有真正将结构体实例化才能够分配内存空间

基本的实例化形式

    var ins T

T是我们定义的结构体类型,ins是我们要实例化的实例

创建指针类型的结构体

    ins := new(T)

T是类型,也可以是结构体、整型、字符串
ins在这里被实例化了,所以ins的类型为T 但是代表的是指针

type Player struct {
	Name string
	Guns string
	Age  int
}

func main() {
	tom := new(Player)
	tom.Name = "tom"
	tom.Guns = "AK47"
	tom.Age = 18
	fmt.Println(tom)
}

&{tom,AK47,18}

go在访问指针型结构体时,也能够直接使用“.”来进行访问,是因为go加入了一个语法糖,能够将ins.Name的形式转化为(*ins).Name

直接使用key value的方式初始化

    type ins struct{
        key1 : value1,
        key2 : value2
    }

也可以直接忽略key进行赋值,不过有些点需要注意

  1. 必须初始化所有的字段
  2. 顺序保持一致
  3. 键值对与值列表的初始化形式不能混用
type Address struct {
    Province    string
    City        string
    ZipCode     int
    PhoneNumber string
}

addr := Address{
    "四川",
    "成都",
    610000,
    "0",
}

fmt.Println(addr)

{四川 成都 610000 0}

匿名结构体初始化

匿名结构体不需要类型名,也不需要type定义就可以直接使用

ins := struct {
    // 匿名结构体字段定义
    字段1 字段类型1
    字段2 字段类型2}{
    // 字段值初始化
    初始化字段1: 字段1的值,
    初始化字段2: 字段2的值,}

也可以不用直接进行初始化

ins := struct {
    // 匿名结构体字段定义
    字段1 字段类型1
    字段2 字段类型2}

例子:

func getStruct(msg *struct {
	name string
	age  int
}) {
	fmt.Println(msg)
	fmt.Printf("%T", msg)
}

func main() {
	msg := &struct {
		name string
		age  int
	}{
		name: "tom",
		age:  18,
	}
	fmt.Println(*msg)
	getStruct(msg)
}

go语言构造函数

go本身是不具有构造函数这一特性的,不过我们可以通过结构体不同的初始化方式而进行模拟

type usr struct{
    name string
    age int
}

func NewUsrName(name string) *usr{
    return &usr{
        name:name
    }
}
func NewUsrAge(age int)*usr{
    return &usr{
        age:age
    }
}

方法和接收器

    func (自定义名 结构体类型)函数名(){
    }

方法类似于面向对象中,在类中声明的函数,属于该结构体的方法

方法参数又分为普通和指针类型两种,普通的在方法内部无法改变实例化的值,而指针类型可以

package main

import "fmt"

type Person struct {
	name string
}

func (per Person) changeName() {
	per.name = "tom"
}
func (per *Person) changeName2() {
	per.name = "tom"
}
func main() {
	per := Person{
		name: "",
	}
	per2 := &Person{
		name: "",
	}
	per2.changeName2()
	fmt.Printf("per: %v\n", per)
	fmt.Printf("per2: %v\n", per2)
}

per:{}
per2:&{tom}

类型内嵌和结构体内嵌

结构体内部可以出现多个匿名字段,这些字段不具有名字,但是必须具有类型名,类型名在这时就成为了字段名

我们可以用这种形式来模拟继承

package main

import "fmt"

type Person1 struct {
	name string
	age  int
}
type Person2 struct {
	Person1
	name1 string
	age1  int
}

func main() {
	per2 := Person2{
		Person1{
			name: "tom",
			age:  18,
		},
		"jerry",
		20,
	}
	fmt.Printf("per2.name: %v\n", per2.name)
}

我们会发现当我们去调用把Person1 内嵌到Person2中时,我们调用Person1中的name时,不需要使用ins.a.b.c的方法 而是直接使用ins.a的方法就可以,当然,如果被内嵌的结构体中有相同的字段名,优先使用被内嵌结构体中的字段

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值