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 := Person{Id: 20001, Name: "LeoLee", Age: 26}
s1 := Student{baseInfo: 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 = &Student{baseInfo: pp}
(*s3).array[0] = 1
fmt.Printf("s3=%v, s3 type=%T\n", s3, s3)
}
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 := &line{startPoint: coordinates{x: 1, y: 1}, endPoint: coordinates{x: 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 := [...]int{8, 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])
}