作者:情人有意_119 | 来源:互联网 | 2023-01-15 22:30
结构体structGo中的struct与C中的struct非常相似,并且Go没有class使用type<Name>struct{}定义结构,名称遵循可见性规则
结构体struct
- Go中的struct与C中的struct非常相似,并且Go没有class
- 使用
typestruct{}
定义结构,名称遵循可见性规则
- 支持指向自身的指针类型成员
- 支持匿名结构,可用作成员或定义成员变量
- 匿名结构也可以用于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)
fmt.Println(a.person.name)
}
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{
return r.width*r.height
}
方法
- Go中虽然没有class,但依旧有method
- 通过显示说明receiver来实现与某个类型的组合
- 只能为同一个包中的类型定义方法
- Receiver可以是类型的值或指针
- 不存在方法重载
- 可以使用值或指针来调用方法,编译器会自动完成转换
- 从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数
- 如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法
- 类型别名不会拥有底层类型所附带的方法
- 方法可以调用结构中的非公开字段
- 使用
type person struct {
name string
sex int
}
func (p person)sayHello(){
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()
(*TZ).Print(&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
}