您的位置:首页 > 编程语言 > Go语言

golang结构体struct学习笔记

2017-09-08 09:48 375 查看

结构体struct

Go中的struct与C中的struct非常相似,并且Go没有class

使用
type<Name>struct{}
定义结构,名称遵循可见性规则

支持指向自身的指针类型成员

支持匿名结构,可用作成员或定义成员变量

匿名结构也可以用于map的值

可以使用字面值对结构进行初始化

允许直接通过指针来读写结构成员

相同类型的成员可进行直接拷贝赋值

支持
==
!=
比较运算符,但不支持
>
<


支持匿名字段,本质上是定义了以某个类型名为名称的字段

嵌入结构作为匿名字段看起来像继承,但不是继承

可以使用匿名字段指针

在函数,属于值拷贝,如果要改原值,需要修改指针。

“`

type person struct{

name string

age int

}

func A(per *person){

per.age = 13

}

如果需要改的次数过多,需要先取指针(推荐)

a := &person{
name :"Joe",
age:19,
}
a.name = "xiaoming" //直接操作指针就可以

A(a)
B(a)

func A(per *person){
per.age = 13
}

func B(per *person){
per.age = 15
}


基本使用

type person struct{
Name string
Age int
}
func main(){
a:= person{
Name:"Joe"
}
a.Age = 19
fmt.Println(a)
}


匿名结构

func main(){
// a := struct{
a := &struct{
name string
age int
}{
name:"xiaoming",
age:19,
}

fmt.Println(a)
}


嵌套匿名结构体

type person struct{
name string
age int
contact struct{
phone, city string
}
}

func main(){
a := person{name:"joe",age:19}
a.contact.phone = "122332"  // 只能这样赋值
a.contact.city = "beijing"
fmt.Println(a)
}


匿名字段

type person struct{
string
int
}
func main(){
a := person{"joe",19}   // 顺序不能出错
fmt.Println(a)
}


继承

type human struct{
sex int
}
type teacher struct{
human
name string
age int
}
type student struct{
human
name string
age int
}

func main(){
a := teacher{name:"han",age:12,human:human{sex:1}}
b := student{name:"zhang",age:19,human:human{sex:0}}
a.name = "joe"
a.age = 13
a.sex = 100
fmt.Println(a)
}


内外层有同名属性

type person struct{
name string
age int
}
type student struct{
person
name string
age int
}

func main(){
a := student{name:"zhangsan",age:12,person:person{name:"lisi",age:20}}
fmt.Println(a.name)  // zhangsan
fmt.Println(a.person.name)  //lisi
}

// 嵌入级别大于1个的时候 ,不允许有同名属性,否则编译报错


Struct

type person struct{
name string
age int
}


使用:

var P person || P := {"Tom",25} || P := {age:24,name:"Tom"}
P.name = "xiaoming"
P.age = 12
fmt.Println(P)

r1 := new(Rect)
r2 := &Rect{}
r3 := &Rect{0,0,100,200}
r4 := &Rect{width:100,height:200}


还有其他几种声明使用方式

1. 按照顺序提供初始化值

P := person{“Tom”,25}

2. 通过 field:value 的方式初始化,这样可以任意顺序

P := person{age:24,name:”Tom”}

3. 当然也可以通过new函数分配一个指针,此处P的类型为 *person

P := new(person)

匿名字段

type Human struct {
name string
age int
weight int
}

type Student struct {
Human  // 匿名字段,那么默认Student就包含了Human的所有字段
speciality string
}


方法(method)

func (r ReceiverType) funcName(parameters)(results)

func (r Rectangle) area() float64{
re
4000
turn r.width*r.height
}


方法

Go中虽然没有class,但依旧有method

通过显示说明receiver来实现与某个类型的组合

只能为同一个包中的类型定义方法

Receiver可以是类型的值或指针

不存在方法重载

可以使用值或指针来调用方法,编译器会自动完成转换

从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数

如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法

类型别名不会拥有底层类型所附带的方法

方法可以调用结构中的非公开字段

使用

type person struct {
name string
sex int
}
func (p person)sayHello(){   //(p是参数,person是接收者的类型)
fmt.Println("我是person")
}

func main()  {
a := person{}
a.sayHello()
}


方法里面改变结构体的属性 -> 传递指针

type A struct{
name string
}
func main(){
a := A{}
a.Print()
fmt.Println(a.name)
}

func(a *A)Print(){
a.name = "aa"
fmt.Println("A")
}


底层类型的结构定制(只有当前包中有效)

type TZ int
func main(){
var a TZ
a.Print()
}

func (a *TZ)Print(){
fmt.Println("TZ")
}


method expression -> 直接通过类型调用,而不用通过变量来调用

type TZ int
func main(){
var a TZ
a.Print()  // method value 通过变量来调用方法
(*TZ).Print(&a)  // (*TZ)是receiver,&a是变量
}

func (a *TZ)Print(){
fmt.Println("TZ")
}


method冲突,和struct一样

通过method修改变量的值

type TZ int
func main(){
var a TZ
fmt.Println(a)
a.AutoAdd()
fmt.Println(a)
}
func (tz *TZ)AutoAdd(){
*tz += 100
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 struct