5.1 结构和方法

一、Go语言的面向对象

  1. go语言仅支持封装,不支持继承和多态

  2. go语言没有class,只有struct

二、结构的定义

  1. 结构

    type 名字 struct{
        i, j int
    }
  2. 使用:

    // 创建treeNode,value为0,left与right为nil
    var root treeNode
    fmt.Println(root)
    
    // 定义并赋值
    root2 := treeNode{value: 3}
    root2.left = &treeNode{}
    root2.right = &treeNode{5, nil, nil}
    root2.right.left = new(treeNode)
    fmt.Println(root2)
    
    // 切片中的定义
    nodes := []treeNode{
        {value: 3},
        {},
    	{6, nil, &root},
    }
    fmt.Println(nodes)

    注意:无论地址还是结构本身,一律使用.来访问成员

  3. 因为Go语言没有构造函数,因此可以使用工厂函数(普通函数)控制构造

    // 定义工厂函数
    func createNode(value int) *treeNode {
    	return &treeNode{value: value}
    }
    
    // 调用工厂函数方式
    root2.left.right = createNode(2)

    注意:

    1. 使用自定义工厂函数

    2. 注意返回了局部变量的地址

  4. 结构创建在堆上还是栈上:不需要知道!!

  5. 定义结构方法

    // 为结构定义方法,接收方法是(node treeNode)
    func (node treeNode) print() {
    	fmt.Println(node.value)
    }
    // 调用方式
    root2.print()
    
    // 第二种写法
    func print(node treeNode) {
    	fmt.Println(node.value)
    }
    // 调用方式
    print(root2)

    注意:定义方法中是传值的(上面操作之后,原值不改变)

    显示定义和命名方法接受者

  6. 由于传值方式是值传递,因此可以使用指针进行引用传递

    // 赋值操作
    func (node *treeNode) setValue(value int) {
    	node.value = value
    }

    备注:

    1. 只有指针才可以改变结构内容

    2. nil指针也可以调用方法

  7. 遍历

    // 遍历
    func (node *treeNode) traveres() {
    	if node == nil {
    		return
    	}
    	node.left.traveres()
    	node.print()
    	node.right.traveres()
    }

    注意:先左子树,在本节点,后右子树

三、值接收者和指针接收者

  1. 要改变内容,必须使用指着接收者

  2. 结构过大也考虑使用指针接收者

  3. 一致性:如果有指针接收者,最好都是指针接收者

  4. 值接收者是Go语言特有的

  5. 值/指针接收者均可接收值/指针

Last updated

Was this helpful?