golang之结构体详解/成员方法实现/继承组合/细节内容

结构体

go语言的面向对象由结构体实现,结构体是值类型,可以使用new来创建。

定义

结构体定义如下所示:

type identifier struct{
    filed1 type
    filed2 type
}

filed就是结构体的字段名字,type是字段的类型,如果暂时不知道命名,可以使用 _ 来进行占位。字段可以使用任何类型,甚至是结构体本身,也可以是函数或者接口。

初始化

初始化类似c++,可以直接声明后赋值,也可以用new关键字分配,具体如下操作

package main

type ListNode struct {
	Val  int
	Next *ListNode
}
func main() {
    //直接声明
	var node ListNode
	node.Val =1
    //new出来
    node2:=new(ListNode)
	node2.Val=2
}

成员方法

结构体内定义,外部实现

在定义时,你可以发现,type可以是func,所以就为结构体的成员方法提供了一个实现渠道。

package main

import "fmt"

type ListNode struct {
	Val  int
	Next *ListNode
	toString func()
}
func doSth() {
	fmt.Println("do something")
}
func main() {
	var node ListNode
	node.Val =1
	node.toString=doSth
	node.toString()
}

虽然写完发现写得挺离谱的,要说是成员方法,却无法访问node的属性,必须传进去才可以。

结构体外实现真正的成员方法

package main

import "fmt"

type ListNode struct {
	Val  int
	Next *ListNode
}
//值传递下的成员方法,无法改变node真正的属性
func (node ListNode)setVal(val int) {
	node.Val=val
}
//引用传递下的成员方法,可以改变node的真正属性
func (node *ListNode)setVal2(val int) {
	node.Val=val
}
func main() {
	var node ListNode
	node.Val =1
	node.setVal(2)
	fmt.Println(node.Val)
	(&node).setVal2(2)
	fmt.Print(node.Val)
}

字段的辅助字符串

字段的辅助字符串是与字段声明在同一行的字符串,只能通过反射获取

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string "Name"
	Age  int    "Age"
	Sex  int    "Sex"
}

func main() {
	person := Person{}
	person.Name = "Tim"
	person.Age  = 10
	person.Sex  = 1

	for i := 0; i < 3; i++ {
		refTag(person, i)
	}
}

func refTag(p Person, i int) {
	pType := reflect.TypeOf(p)
	iFiled := pType.Field(i)
	fmt.Println(iFiled.Tag)
}

reflect.TypeOf可以获取变量的正确类型,如果变量是一个结构体,就可以通过Filed来索引该结构体的字段,然后就可以使用Tag属性。

匿名字段

go结构体还支持一个特殊字段,匿名字段。这些字段没有显式的名字,只有字段类型,此时字段类型也就是字段的名字,匿名字段也可以是一种结构体。所以相同种类的匿名字段只能有一个。

type Test1 struct {
    t1 int
    t2 int
}

type Test struct {
    a int
    b string
    bool
    Test1
}

func main() {
    test := new(Test)
    test.a = 1
    test.b = "2"
    test.bool = true
    test.t1 = 2
    test.t2 = 3
    
    fmt.Println(test)
}

继承

一个结构体嵌到另一个结构体,称作组合
匿名和组合的区别
如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现继承
如果一个struct嵌套了另一个【有名】的结构体,那么这个模式叫做组合
如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现多重继承

package main

import "fmt"

type ListNode struct {
	Val  int
	Next *ListNode
}
//组合
type TreeNode struct {
	lnode ListNode
}
//继承
type GraphNode struct {
	ListNode
} 
//值传递下的成员方法,无法改变node真正的属性
func (node ListNode)setVal(val int) {
	node.Val=val
}
//引用传递下的成员方法,可以改变node的真正属性
func (node *ListNode)setVal2(val int) {
	node.Val=val
}
func main() {
	var treeNode TreeNode
	treeNode.lnode.setVal2(1)
	var graphNode GraphNode
	graphNode.setVal2(2)
}
发布了16 篇原创文章 · 获赞 3 · 访问量 1349

猜你喜欢

转载自blog.csdn.net/weixin_40631132/article/details/105208402