Go 结构体学习 2021.05.05-08
结构体初始化及结构体指针
package main
import "fmt"
//创建之战类型的结构体
type person struct {
name string
gender string
}
func f(x person) {
x.name = "a2rcher"
x.gender = "a" //修改的时副本的gender
}
func main() {
var p1 person
p1.name = "a2rcher"
p1.gender = "male"
f(p1)
fmt.Println(p1.gender) //输出的值还是male,并不会因为在新定义的f函数种赋的值而改变
f2(&p1)
fmt.Println(p1.gender) //输出的值还是male2
var p2 = new(person)//new内置函数,创造一个内存空间 输出的值*main.person
//p2.name = "a2rcher"
fmt.Printf("%T\n", p2)
fmt.Printf("%p\n", p2)
}
/*注意:
在go语言种,函数的参数永远都是拷贝,意思就是说永远都是副本,并不能修改值。
想要修改值,我们需要修改他的内存地址,就得用到指针
例如f2()函数
*/
func f2(x *person) {
(*x).gender = "male2" //这个x就是个指针,根据内存地址找到原变量,修改原来的变量
//x.gender = "male2" go语言特性 由于没有指针的内存操作,并不需要使用括号括起来,他会自动根据指针判断属性
}
package main
import "fmt"
//创建之战类型的结构体
type person struct {
name string
gender string
}
func f(x person) {
x.name = "a2rcher"
x.gender = "a" //修改的时副本的gender
}
func main() {
var p1 person
p1.name = "a2rcher"
p1.gender = "male"
f(p1)
fmt.Println(p1.gender) //输出的值还是male,并不会因为在新定义的f函数种赋的值而改变
f2(&p1)
fmt.Println(p1.gender) //输出的值还是male2
var p2 = new(person) //new内置函数,创造一个内存空间 输出的值*main.person
//p2.name = "a2rcher"
fmt.Printf("%T\n", p2)
fmt.Printf("%p\n", p2)
fmt.Printf("%#v\n", p3)
fmt.Printf("%#v\n", p4)
fmt.Printf("%#v\n", p5)
}
/*注意:
在go语言种,函数的参数永远都是拷贝,意思就是说永远都是副本,并不能修改值。
想要修改值,我们需要修改他的内存地址,就得用到指针
例如f2()函数
*/
func f2(x *person) {
(*x).gender = "male2" //这个x就是个指针,根据内存地址找到原变量,修改原来的变量
//x.gender = "male2" go语言特性 由于没有指针的内存操作,并不需要使用括号括起来,他会自动根据指针判断属性
}
//结构体指针2
//直接初始化赋值 key:value的方式
var p3 = person{
//相当于定义了一个person指针赋值给了p3 冒号前时key 冒号后时valu
name: "a2rcher",
gender: "male",
}
//使用值列表的形式初始化,值得顺序要个结构体定义字段时得顺序一致
//p4这种方式最为常见
var p4 = person{ //输出main.person{name:"aaaa", gender:"ewrfdsdaf"}
"aaaa",
"ewrfdsdaf",
}
var p5 = &person{ //&取地址符取到person得内存地址 输出&main.person{name:"bbbb", gender:"egsehrtujityut"}
"bbbb",
"egsehrtujityut",
}
package main
import "fmt"
//结构体占用一块连续得内存空间
type x struct {
a, b, c int8
}
func main() {
m := x{
a: int8(10),
b: int8(20),
c: int8(30),
}
fmt.Printf("%p\n", &m.a)
fmt.Printf("%p\n", &m.b)
fmt.Printf("%p\n", &m.c)
}
构造函数初始化结构体
构造函数:返回一个结构体变量得函数
package main
import "fmt"
//构造函数实现初始化
type person struct {
name string
age int
}
//构造函数:约定成俗用new开头
//构造一个函数newPerson 返回person类型的指针
//构造函数的好处就是想使用里面的值得时候直接调用就可以
//当结构体体积比较大的时候尽量使用结构体指针,减少程序内存开销(建议尽量都是用指针 。。。。。巴适)
func newPerson(name string, age int) *person {
return &person{
name: name,
age: age,
}
}
func main() {
p1 := newPerson("a2rcher", 12)
p2 := newPerson("asdasd", 523)
1
fmt.Println(p1, p2)
}
方法和接收者
方法的定义格式:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
函数体
}
- 接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名称首字母的小写,而不是
self
、this
之类的命名。例如,Person
类型的接收者变量应该命名为p
,Connector
类型的接收者变量应该命名为c
等。 - 接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型。
- 方法名、参数列表、返回参数:具体格式与函数定义相同。
package main
import "fmt"
type person struct {
name string
}
//构造函数
func newPerson(name string) person {
return person{
name: name,
}
}
//方法是作用与特定类型得函数
//接收者表示的是调用该方法的具体类型变量。多用于类型名首字母小写表示
//可以理解为python中的self 或者php中的this
//
func (p person) a2rcher() {
fmt.Printf("%s:aaaaa", p.name)
}
func main() {
p1 := newPerson("asdasd")
p1.a2rcher()
}
//