首页 > 其他分享 >05-Go方法、接口、泛型

05-Go方法、接口、泛型

时间:2023-04-04 18:55:50浏览次数:32  
标签:Println 05 fmt 接口 --- 泛型 func 类型 Go

1 方法

//方法 
  1.是特殊的函数,可以自动传值 ---> 对象(go中就是结构体)来调用,自动把对象(当前结构体的实例)传过来

  2.在func关键字 和 方法名 中间加入了一个特殊的接收器类型
    接收器可以是结构体类型或者是非结构体类型
    接收器是可以在方法的内部访问的
  
  3.方法是绑定给结构体的 ---> 如何绑定


  4.方法如何给非结构体类型绑定  ---> 将 非结构体类型 重命名,再绑定
    
  eg:
    type Myint int8

    func (p *Myint) add(){
        (*p) +=1
    }


//总结:go中没有面向对象的概念,但是能够实现面向对象
  1.结构体            --->  类的一半,只有属性
  2.结构体 + 匿名字段  --->  类的继承
  3.结构体 + 方法      --->  类的另一半,类中的方法   实例化结构体后,可以自动传值(当前对象)



package main

import "fmt"


//定义了一个结构体
type Person1 struct {
    name string
    age  int
}


//给结构体绑定方法   
func (p Person1) PrintName() { 
    fmt.Println(p.name)
}


// (p Person1)   值类型接收器,接受的是当前结构体的实例(当前对象) 的copy一份
func (p Person1) ChangeName(name string) {
    p.name = name   //修改该结构体的实例 属性,不会影响原来结构体实例
    fmt.Println(p)
}

// (p *Person1)  指针类型接收器,接受的是当前结构体的实例(当前对象) 的指针 
                               就是python中的self,是原值的引用
func (p *Person1) ChangeAge(age int) {
    p.age = age    //修改该结构体的实例 属性,会影响原来结构体实例
    fmt.Println(p)
}


//定义的是打印name的函数
func PrintName(p Person1) {

}



func main() {
    //1 使用方法
    var p Person1=Person1{"lqz",19}
    p.PrintName()

    
    //2 为什么我们已经有函数了还需要方法呢
        区别在于:使用方式 和 自动传值
    
    PrintName(p)  //函数调用,需要手动传参
      

    //3 指针接收器与值接收器 ---> 取别在于修改会不会影响原来的对象
    var p Person1 = Person1{"lqz", 19}
    
    p.ChangeName("彭于晏")
    fmt.Println("修改后的:",p)  //{"lqz", 19}  没有改

    
    //5 接收器使用场景 ---> 如果想改原来的值,用指针类型接收器
    var p Person1 = Person1{"lqz", 19}
    
    p.ChangeAge(99)
    fmt.Println("修改后的:",p) //{"lqz", 99}  修改


    //5 匿名字段的方法 ---> 方法提升
    p:=Person2{"lqz",18,Hobby2{"篮球",1}}
    fmt.Println(p)
    
    //p.hobby.printName()
    p.printName()  //方法提升了

}


//5 匿名字段的方法 ---> 方法提升
type Hobby2 struct {
    hobbyName string
    hobbyId int
}

type Person2 struct {
    name string
    age int
    //hobby Hobby2
    Hobby2  //匿名字段
}

func (h Hobby2) printName()  {
    fmt.Println(h.hobbyName)
}

2 接口

//接口:   就是python中的多态
  1.一系列方法的集合,约束子类的行为

  2.go也是鸭子类型,是非侵入式接口


//侵入式接口和非侵入式接口
  非侵入式接口:删除接口后,基于该接口的结构体不会报错   eg: go

  侵入式接口:删除接口后,基于该接口的类会报错   eg:java



package main

import (
    "fmt"
)

//定义一个鸭子接口
type Duck interface {
    run()
    speak()
}

//定义一个空接口 ---> 所有类型都实现了空接口
type Empty interface {
}


//定义普通鸭结构体
type PDuck struct {
    age  int
    name string
}

//定义唐老鸭结构体
type TDuck struct {
    age  int
    name string
    wife string
}


//让普通鸭实现Duck接口 ---> 只要实现了接口中所有方法,就叫实现该接口
func (p PDuck) run() {
    fmt.Println("普通鸭子,走路歪歪扭扭")
}
func (p PDuck) speak() {
    fmt.Println("普通鸭子,嘎嘎叫")
}


//让唐老鸭实现Duck接口 ---> 只要实现了接口中所有方法,就叫实现该接口
func (p TDuck) run() {
    fmt.Println("人走路")
}
func (p TDuck) speak() {
    fmt.Println("人叫")
}




func main() {
    var p PDuck = PDuck{1, "肉鸭一号"}
    var t TDuck = TDuck{5, "唐老鸭", "母唐老鸭"}
    
    //唐老鸭和普通鸭,都可以赋值给鸭子接口类型,就可以都当做 鸭子接口 去操作
    var d Duck
    d = p
    d = t
    
    d.run()
    d.speak()

    
    //1 类型断言  d.(类型): 判断该接口是否 是这个类型,并返回该类型对应的值
                     作用:可以通过 接口类型,获取到原本类型的实例
                     返回值: 获取该对象、布尔值
    
    if v,ok := d.(TDuck); ok{
        fmt.Println(v.name)
    }else {
        fmt.Println("断言失败,不是唐老鸭类型")
    }

        
    //2 空接口类型  所有类型都可以赋值给空接口
    var a Empty=1
    
    a="lqz"
    a=[]int{1,2,3}
   
    //3 匿名空接口  
    interface{}
    
    
    //5 类型选择  就是 类型断言 + Switch + 空接口 的结合
    a := "lqz"
    a := []int{1, 2, 3}
    test(a)
    
    t := TDuck{wife: "李易峰"}
    test(t)
}

    
//5 类型选择  作用:可以通过 接口类型,获取到原本类型的实例

//func test(i interface{}){    //函数参数 是 匿名空接口
func test(i Empty) {
    switch v:=i.(type) {   // i.(type)可以返回i对应类型的值,但.(type)只能在switch内使用
    case int:
        fmt.Println("是int")
    case string:
        fmt.Println("是字符串")
    case TDuck:
        fmt.Println(v.wife)
        fmt.Println("是唐老鸭类型")
    default:
        fmt.Println("不知道什么类型")
    }
}


3 泛型

//泛型编程
  通过引入 类型形参 和 类型实参 这两个概念
  让一个函数获得了处理多种不同类型数据的能力


//理解案例:
  定义一个int类型的add函数,但是不能处理int以外的类型
  
  泛型就是将add函数的 参数类型不固定,等到实际传入参数时,再给定具体类型
  从而实现同一个函数,处理 除类型以外的 相同逻辑的功能 

  python 没有泛型一说,但是可以通过 注释等提示,实现人为约束的 泛型
  因为python本身就是动态类型,变量没有固定类型,可以指向所有类型
  是一切皆对象,都是对象的引用
  传入什么对象,就是什么对象的类型使用


//使用场景
  如果你经常要分别为不同的类型写完全相同逻辑的代码,那么使用泛型将是最合适的选择


//具体实现   参考 https://segmentfault.com/a/1190000041634906

标签:Println,05,fmt,接口,---,泛型,func,类型,Go
From: https://www.cnblogs.com/Edmondhui/p/17287626.html

相关文章

  • 06-信道、互斥锁、异常处理、Gin框架beego的使用
    1goroutine协程//1并发和并行并发:同一时间段内,多个任务在执行(单个cpu,执行多个任务)并行:同一时刻,多个任务在执行(多个cpu的支持)//注:编程语言中,因为Python有GIL全局解释器锁,导致同一时刻,同一个进程中只能运行一个线程===>延伸出开启多进程,解决利用上多核优......
  • 开源好物推荐:全栈测试平台RunnerGo
    做软件测试的同学在工作时应该都碰到过这种情况:接口管理、接口测试用postman、Apipost等接口管理工具,性能测试用jmeter、loadrunner等性能测试工具,接口自动化则是jmeter脚本或者python脚本配合jenkins使用。这种情况极大的降低了研发效率,今天给大家推荐一款入选GiteeGVP的开源......
  • 「刷起来」Go必看的进阶面试题详解
    勤学如春起之苗,不见其增日有所长;辍学如磨刀之石,不见其损日有所亏。本文的重点:逃逸分析、延迟语句、散列表、通道、接口。1.逃逸分析逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详......
  • Demo05
    包机制  packagecom.zhang.base; /** *@authorKaungshen *@version1.0 *@since1.8 */ publicclassDoc{ ​   Stringname; ​   /**   *@authorKaungshen   *@paramname   *@return   *@throwsException......
  • Python系列005
    控制设备仪器————电源初识importpyvisa#ConnecttotheGPIBinstrumentrm=pyvisa.ResourceManager()classPiDevice:def__init__(self,addressId):self.addressId=addressIddefPiPower(self):whoPower=rm.open_resource(self.a......
  • Django外键引用User模型时显示username的解决方法
    问题需求:在DjangoAdmin后台模型管理中,引用User外键的字段,显示的是username(用户名)。下拉菜单要显示姓名(last_name和first_name,外加username保持唯一性、可辨别性)。使用代理模型(proxymodel)fromdjango.dbimportmodelsfromdjango.contrib.auth.modelsimportUser#创建代......
  • django笔记2
    Django开发主题:员工管理系统1.新建项目2.创建apppythonmanage.pystartappapp01注册app:3.设计表结构(django)fromdjango.dbimportmodelsclassDepartment(models.Model):"""部门表"""title=models.CharField(verbose_name='标......
  • MPU6050陀螺仪与Processing和上位机飞控联动实录
    简而言之,MPU6050=三轴MEMS陀螺仪+三轴MEMS加速度计+可扩展数字运动处理器DMP,它可进行姿态解算(Pitch、Yaw、Roll角),我们还可以外接ProcessingIDE,或外接匿名上位机(V7),实时绘制系统的飞行姿态,下面讲一下整个联调过程以及遇到的坑。 图0单片机与上位机(V7)飞行姿态联动......
  • C#中的泛型(部分应用)
    泛型(Generic)顾名思义:就是广泛的类型。在不确定使用什么类型时先占用一个类的位置。语法:泛型类<T>   其中T表示未知类型(可能是:string,int,bool......)作为一个占位符,代替实际的类型,一般常用泛型标识:T,K。publicclassGeneric<T>//泛型方法:让方法也支持多种类型{//......
  • Goalng:基础复习一遍过
    Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。  剖析Helloworld  新建文件main.go写入以下内容:packagemainimport"fmt"funcmain(){fmt.Println("HelloWorld!")}其中,packgemain 的作用是声明了mai......