Golang:struct定义与试用以及内存分析
Posted 保暖大裤衩LeoLee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang:struct定义与试用以及内存分析相关的知识,希望对你有一定的参考价值。
概述
Golang虽然具有OOP的特性,但是并没有类的概念,也没有继承关键字。
提供了一个类似于类功能,但是又截然不同的概念:结构体struct。
定义
有四种定义方式:
package main
import "fmt"
//struct定义
type Person struct
Id int64
Name string
Age int8
type Student struct
baseInfo Person
ptr *int //指针
array [2]int
slice []int
map1 map[string]int
func changePerson(p Person)
p.Name = "Lydia"
func main()
//struct的四种声明方式
//方式一:直接声明
var s Student
fmt.Println("s=", s)
//方式二:类型推断+初始化
pp := PersonId: 20001, Name: "LeoLee", Age: 26
s1 := StudentbaseInfo: pp
fmt.Println("s1=", s1)
//方式三:内建函数new,返回结构体指针
var s2 *Student = new(Student)
//赋值方法:获取指针的值(*s2),然后再进行赋值
(*s2).baseInfo = pp
//为了方便程序员,golang的作者也允许如下写法,隐式的对指针s2进行取值运算(*),再进行赋值。属于语法糖
s2.array[0] = 1
s2.array[1] = 2
fmt.Printf("s2=%v, s2 type=%T\\n", s2, s2)
//方式四:使用&符,返回结构体指针
var s3 *Student = &StudentbaseInfo: pp
(*s3).array[0] = 1
fmt.Printf("s3=%v, s3 type=%T\\n", s3, s3)
struct初始化完成后,各个属性为其类型的默认值:
package main
import "fmt"
//struct定义
type Person struct
Id int64
Name string
Age int8
func main()
//定义Person类型的变量stu1
var p1 Person
fmt.Printf("p1.Id=%d,p1.Name=%s,p1.Age=%d\\n", p1.Id, p1.Name, p1.Age) //初始化变量完成后,各个字段为类型的默认值
p1.Id = int64(1000)
p1.Name = "LeoLee"
p1.Age = 26
fmt.Printf("p1.Id=%d,p1.Name=%s,p1.Age=%d\\n", p1.Id, p1.Name, p1.Age)
复杂结构体示例
package main
import "fmt"
//struct定义
type Person struct
Id int64
Name string
Age int8
type Student struct
baseInfo Person
ptr *int //指针
array [2]int
slice []int
map1 map[string]int
func main()
var stu1 Student
fmt.Println(stu1)
//prt、slice、map都为nil,prt是因为没有指向内存,slice和map是因为没有make
if stu1.ptr == nil
fmt.Printf("stu1.ptr=%v\\n", stu1.ptr)
//指针类型赋值
i := 8
stu1.ptr = &i
fmt.Printf("stu1.ptr[%p], value=%d\\n", stu1.ptr, *stu1.ptr)
if stu1.slice == nil
fmt.Printf("stu1.slice=%v\\n", stu1.slice)
//初始化slice
stu1.slice = make([]int, 2)
stu1.slice[0] = 1
stu1.slice[1] = 2
stu1.slice = append(stu1.slice, 3)
if stu1.map1 == nil
fmt.Printf("stu1.map1=%v\\n", stu1.map1)
//初始化map
stu1.map1 = make(map[string]int)
stu1.map1["A"] = 5
stu1.map1["B"] = 6
stu1.baseInfo.Name = "LeoLee"
fmt.Println(stu1)
引用传递
package main
import "fmt"
//struct定义
type Person struct
Id int64
Name string
Age int8
func changePerson(p Person)
p.Name = "Lydia"
func main()
var p1 Person
p1.Id = int64(1000)
p1.Name = "LeoLee"
p1.Age = 26
//struct是值传递类型,函数内的修改无法影响函数外的值。
//需要进行指针才可以改变原有变量的数据
changePerson(p1)
fmt.Printf("p1.Id=%d,p1.Name=%s,p1.Age=%d\\n", p1.Id, p1.Name, p1.Age)
p2 := p1
p2.Name = "Lydia"
fmt.Printf("p1.Id=%d,p1.Name=%s,p1.Age=%d\\n", p1.Id, p1.Name, p1.Age)
fmt.Printf("p2.Id=%d,p2.Name=%s,p2.Age=%d\\n", p2.Id, p2.Name, p2.Age)
p3 := &p1
p3.Name = "Tony"
fmt.Printf("p1.Id=%d,p1.Name=%s,p1.Age=%d\\n", p1.Id, p1.Name, p1.Age)
fmt.Printf("p3.Id=%d,p3.Name=%s,p3.Age=%d\\n", p3.Id, p3.Name, p3.Age)
结构体之间强转
package main
import "fmt"
type A struct
Num int
type B struct
Num int
//结构体进行type重新定义,相当于取别名
type AA A
type Integer int //基本数据类型也可以
func main()
//结构体之间的转换
var a A
var b B
a = A(b) //两个结构体之间字段数量、字段类型、字段名称一致,可以强制转换
fmt.Println(a, b)
//结构体进行type重新定义,相当于取别名
var integer Integer = 10
var i int = 20
i = int(integer) //并不能直接i = j,虽然本质上都是int,但是golang认为并不是同一种数据类型了,还是需要强转
fmt.Println(integer, i)
结构体内存简单分析
package main
import "fmt"
//坐标点
type coordinates struct
x, y int
//线
type line struct
startPoint, endPoint coordinates
array *[2]int
func main()
//定义一条直线
l1 := &linestartPoint: coordinatesx: 1, y: 1, endPoint: coordinatesx: 3, y: 6
fmt.Printf("l1 type=%T\\n", l1)
fmt.Printf("l1=%v\\n", l1)
//通过内存地址可以看出这四个值在内存里是连续的:0xc0000101a0,0xc0000101a8,0xc0000101b0,0xc0000101b8
//每个字段地址之间相差8个字节,int类型在64位操作系统中占用8个字节
fmt.Printf("l1.startPoint.x=%v, address=%p\\n", l1.startPoint.x, &l1.startPoint.x)
fmt.Printf("l1.startPoint.y=%v, address=%p\\n", l1.startPoint.y, &l1.startPoint.y)
fmt.Printf("l1.endPoint.x=%v, address=%p\\n", l1.endPoint.x, &l1.endPoint.x)
fmt.Printf("l1.endPoint.y=%v, address=%p\\n", l1.endPoint.y, &l1.endPoint.y)
//如果结构体中的某个字段是指针类型,那么该指针对应的值就不一定是连续的了,但是指针自己的地址在该结构体中仍然是连续的
//可以看到l1.array[0]和l1.array[1]的地址与l1.endPoint.y并不连续,但是l1.array与l1.endPoint.y连续
a1 := [...]int8, 9
(*l1).array = &a1
fmt.Printf("l1.array address=%p\\n", &l1.array)
fmt.Printf("l1.array[0]=%v, address=%p\\n", l1.array[0], &l1.array[0])
fmt.Printf("l1.array[1]=%v, address=%p\\n", l1.array[1], &l1.array[1])
以上是关于Golang:struct定义与试用以及内存分析的主要内容,如果未能解决你的问题,请参考以下文章