zoukankan      html  css  js  c++  java
  • go二叉树、struct、接口

    二叉树实现、及遍历

    二叉树定义

    type Student struct {
           Name string
           left* Student
           right* Student
    }
    

     如果每个节点有两个指针分别用来指向左子树和右子树,我们把这样的
    结构叫做二叉树

    package main
    
    import "fmt"
    
    type Student struct {
    	Name  string
    	Age   int
    	Score float32
    	left  *Student
    	right *Student
    }
    
    func trans(root *Student) {
    	if root == nil {
    		return
    	}
    	fmt.Println(root)
    
    	trans(root.left)
    	trans(root.right)
    
    }
    
    func main() {
    	var root *Student = new(Student)
    
    	root.Name = "stu01"
    	root.Age = 18
    	root.Score = 100
    
    	var left1 *Student = new(Student)
    	left1.Name = "stu02"
    	left1.Age = 18
    	left1.Score = 100
    
    	root.left = left1
    
    	var right1 *Student = new(Student)
    	right1.Name = "stu04"
    	right1.Age = 18
    	right1.Score = 100
    
    	root.right = right1
    
    	var left2 *Student = new(Student)
    	left2.Name = "stu03"
    	left2.Age = 18
    	left2.Score = 100
    
    	left1.left = left2
    
    	trans(root)
    }
    

    struct初始化

    1、结构体是用户单独定义的类型,不能和其他类型进行强制转换

    type Student struct {
            Number int
    }
    
    type Stu Student //alias
    
    var a Student
    a = Student(30)
    
    var b Stu
    a = b
    

     2、golang中的struct没有构造函数,一般可以使用工厂模式来解决这个问题

    Package model
    type student struct {
           Name stirng
        Age int
    }
    
    func NewStudent(name string, age int) *student {
    return &student{
           Name:name,
           Age:age,}
    }
    
    Package main
    S := new (student)
    S := model.NewStudent(“tony”, 20)
    

     再次强调:

    • make 用来创建map、slice、channel
    • new用来创建值类型

    struct中的tag

    我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的
          机制获取到,最常用的场景就是json序列化和反序列化

    package main
    
    import (
    	"encoding/json"
    	"fmt"
    )
    
    type Student struct {
    	Name  string `json:"student_name"`
    	Age   int    `json:"age"`
    	Score int    `json:"score"`
    }
    
    func main() {
    	var stu Student = Student{
    		Name:  "stu01",
    		Age:   18,
    		Score: 80,
    	}
    
    	data, err := json.Marshal(stu)
    	if err != nil {
    		fmt.Println("json encode stu failed, err:", err)
    		return
    	}
    
    	fmt.Println(string(data))
    }
    

     匿名字段

    结构体中字段可以没有名字,即匿名字段

    type Car struct {
           Name stirng
        Age int        
    }
    
    type Train struct {
            Car
            Start time.Time
            int
    }
    

     exp:

    package main
    
    import (
    	"fmt"
    )
    
    type Cart1 struct {
    	name string
    	age  int
    }
    
    type Cart2 struct {
    	name string
    	age  int
    }
    
    type Train struct {
    	Cart1
    	Cart2
    }
    
    func main() {
    	var t Train
    
    	t.Cart1.name = "train"
    	t.Cart1.age = 100
    
    	fmt.Println(t)
    }
    

     匿名字段冲突处理

    type Car struct {
           Name string
        Age int        
    }
    
    type Train struct {
            Car
            Start time.Time
            Age int
    }
    
    type A struct {
           a int
    }
    
    type B struct {
            a int
            b int
    }
    
    type C struct {
           A
           B
    }
    

     方法

    1、Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以
          有方法,而不仅仅是struct

    定义:func (recevier type) methodName(参数列表)(返回值列表){}
    

    2、方法和函数的区别

    • 函数调用: function(variable, 参数列表)
    • 方法:variable.function(参数列表)

    3、指针receiver   vs 值receiver
      本质上和函数的值传递和地址传递是一样的


    4. 方法的访问控制,通过大小写控制
        

    exp:

    package main
    
    import "fmt"
    
    type integer int
    
    func (p integer) print() {
    	fmt.Println("p is ", p)
    }
    
    func (p *integer) set(b integer) {
    	*p = b
    }
    
    type Student struct {
    	Name  string
    	Age   int
    	Score int
    	sex   int
    }
    
    func (p *Student) init(name string, age int, score int) {
    	p.Name = name
    	p.Age = age
    	p.Score = score
    	fmt.Println(p)
    }
    
    func (p Student) get() Student {
    	return p
    }
    
    func main() {
    	var stu Student
    	stu.init("stu", 10, 200)
    
    	stu1 := stu.get()
    	fmt.Println(stu1)
    
    	var a integer
    	a = 100
    	a.print()
    
    	a.set(1000)
    	a.print()
    }
    

    5、继承

    • 如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。
    • 继承字段、继承方法
    package main
    
    import "fmt"
    
    type Car struct {
    	weight int
    	name   string
    }
    //继承方法
    func (p *Car) Run() {
    	fmt.Println("running")
    }
    //继承 type Bike struct { Car lunzi int } //组合 type Train struct { c Car } func main() { var a Bike a.weight = 100 a.name = "bike" a.lunzi = 2 fmt.Println(a) a.Run()//继承 var b Train b.c.weight = 100 b.c.name = "train" //组合 b.c.Run() }

     6、组合和匿名字段

    •   如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问      匿名结构体的方法,从而实现了继承。
    •   如果一个struct嵌套了另一个有名结构体,那么这个模式就叫组合。

    7、多重继承
      如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问
      多个匿名结构体的方法,从而实现了多重继承。
    8、实现String()

    •   如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出。
    •       接口的一种实现方式
    package main
    
    import "fmt"
    
    type Car struct {
    	weight int
    	name   string
    }
    
    func (p *Car) Run() {
    	fmt.Println("running")
    }
    
    type Bike struct {
    	Car
    	lunzi int
    }
    
    type Train struct {
    	Car
    }
    
    func (p *Train) String() string {
    	str := fmt.Sprintf("name=[%s] weight=[%d]", p.name, p.weight)
    	return str
    }
    
    func main() {
    	var a Bike
    	a.weight = 100
    	a.name = "bike"
    	a.lunzi = 2
    
    	fmt.Println(a)
    	a.Run()
    
    	var b Train
    	b.weight = 100
    	b.name = "train"
    	b.Run()
    
    	fmt.Printf("%s", &b)
    }
    

    接口

    1. 定义     


    Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能
    包含任何变量。

    2. 定义


    type example interface{

            Method1(参数列表) 返回值列表
            Method2(参数列表) 返回值列表
            …
    }

    3. interface类型默认是一个指针

    4. 接口实现
      a. Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中
        的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement
        类似的关键字
      b. 如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个
        接口。

    5. 接口实现
          
    a. Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中
      的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement
      类似的关键字
    b. 如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个
      接口。
    c. 如果一个变量只含有了1个interface的方部分方法,那么这个变量没有实现
      这个接口。

    6. 多态
          
      一种事物的多种形态,都可以按照统一的接口进行操作

    package main
    
    import "fmt"
    
    type People struct {
    	name string
    	age  int
    }
    
    type Test interface {
    	Print()
    	Sleep()
    }
    
    type Student struct {
    	name  string
    	age   int
    	score int
    }
    
    func (p Student) Print() {
    	fmt.Println("name:", p.name)
    	fmt.Println("age:", p.age)
    	fmt.Println("score:", p.score)
    }
    
    func (p Student) Sleep() {
    	fmt.Println("student sleep")
    }
    
    func (people People) Print() {
    	fmt.Println("name:", people.name)
    	fmt.Println("age:", people.age)
    }
    
    func (p People) Sleep() {
    	fmt.Println("people sleep")
    }
    
    func main() {
    
    	var t Test
    	fmt.Println(t)
    	//t.Print()
    
    	var stu Student = Student{
    		name:  "stu1",
    		age:   20,
    		score: 200,
    	}
    
    	t = stu
    	t.Print()
    	t.Sleep()
    
    	var people People = People{
    		name: "people",
    		age:  100,
    	}
    
    	t = people
    	t.Print()
    	t.Sleep()
    
    	fmt.Println("t:", t)
    }
    
  • 相关阅读:
    深入理解javascript函数进阶系列第三篇——函数节流和函数防抖
    深入理解javascript函数进阶系列第二篇——函数柯里化
    深入理解javascript函数进阶系列第一篇——高阶函数
    javascript面向对象系列第四篇——OOP中的常见概念
    CSS以图换字的9种方法
    javascript面向对象系列第三篇——实现继承的3种形式
    使用gitbook
    linux云服务器常用设置
    Git要点
    Linux环境下安装NodeJS和mongoDB
  • 原文地址:https://www.cnblogs.com/dylan123/p/13192573.html
Copyright © 2011-2022 走看看