Golang结构体和指针

结构体定义

定义结构体和C语言一样,使用struct关键字。在结构体内部定义它们的成员变量和类型,只是类型要放到后面,并且变量之间不用逗号。如果成员变量的类型相同的话,可以把它们写到同一行。

type Student struct {
    name   string
    age    int
    weight float32
    score  []int
}

结构体初始化

可以变量初始化和指针初始化,代码如下:

package main

import (
    "fmt"
)

type Student struct {
    name   string
    age    int
    weight float32
    score  []int
}

func main() {
    stu01 := Student{"qixuxiang", 23, 55.5, []int{95, 96, 98}}                //按照字段顺序进行初始化
    stu02 := Student{age: 23, weight: 55.5, score: []int{97, 98}, name: "sb"} //通过 field:value 形式初始化,该方式可以自定义初始化字段的顺序
    var ptu1 = &Student{"qishuangzhu", 23, 55.0, []int{2, 3, 6, 4, 5, 9}}     //初始化得到对象指针
    pp := new(Student)                                  //使用 new 关键字创建一个指针
    *pp = Student{"qishuangming", 23, 65.0, []int{2, 3, 6}}
    fmt.Printf("stu01.age is %d\n", stu01.age)
    fmt.Printf("stu02 have %d subjects\n", len(stu02.score))
    fmt.Printf("stu03's weight is %f\n", (*ptu1).weight)
    fmt.Printf("stu03's weight is %f\n", ptu1.weight) //Go语言自带隐式解引用
    fmt.Printf("stu pp have %d subjects\n", len((*pp).score))
    fmt.Printf("stu pp have %d subjects\n", len(pp.score)) //Go语言自带隐式解引用
    fmt.Printf("stu01 info is %#v\n", stu01)  //结构体可以直接打印
}

Go语言指针

在Go语言中,直接砍掉了C语言指针最复杂的指针运算部分,只留下了获取指针(&运算符)和获取对象(*运算符)的运算,使用方法和C语言很类似。但不同的是,Go语言中没有 -> 操作符来调用指针所属的成员,而与一般对象一样,都是使用 . 来调用

Go语言自带指针隐式解引用 :对于一些复杂类型的指针, 如果要访问成员变量时候需要写成类似 *p.field的形式时,只需要p.field即可访问相应的成员。

示例代码见上面代码的后四行。

值类型和指针类型区别

对于一个函数(或方法),如果函数的参数(或接收者)是对象指针时,表示此对象是可被修改的;相反的,如果是对象时,表示是不可修改的(但如果该对象本身就是引用类型,如 map\func\chan 等,则本质上是可以修改的)。所以一般的做法是,方法的接收者习惯性使用对象指针,而不是对象,一方面可以在想修改对象时进行修改,另一方面也减少参数传递的拷贝成本。

   另外,有一点尤为特殊,如果是作为函数的参数,则函数定义时,是使用对象还是对象指针,是有本质区别的,在使用对象作为参数的函数中,不能传入对象指针,同样的,在使用对象指针作为参数的函数中,也不能传入对象,否则编译器会报错。但如果是方法,则接收者定义为对象还是对象指针,都可以接收对象和对象指针的调用。下面我们来定义相关的函数和方法如下:

package main


import "fmt"

type Player struct{
    userid int
    username string
}


//传入 Player 对象参数
func print_obj(player Player) {
    //player.username = "new"  //修改并不会影响传入的对象本身
    fmt.Println("userid:", player.userid)
}

//传入 Player 对象指针参数
func print_ptr(player *Player){
    player.username = "new01"
    fmt.Printf("userid is %d\n",player.userid)
    fmt.Printf("username is %s\n",player.username)
}

//接收者为 Player 对象的方法,方法接收者的变量,按照 GO 语言的习惯一般不用 this/self ,而是使用接收者类型的第一个小写字母,可以看标准库中的代码风格。
func (p Player) m_print_obj(){
    //p.username = "new02"  修改并不会影响传入的对象本身
    fmt.Printf("userid  is %d\n",p.userid)

}

//接收者为 Player 对象指针的方法
func (p *Player) m_print_ptr(){
    p.username = "new03"
    fmt.Printf("userid  is  %d\n",p.userid)
    fmt.Printf("username is %s\n",p.username)
}



func main(){
    player01 := Player{12 ,"test"}
    pp := &Player {15 ,"newname"}
    print_obj(player01)
    print_ptr(pp)
    player01.m_print_obj()
    pp.m_print_ptr()
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值