go 函数 方法 接口

  • 概论
  • 函数
  • 方法
  • 接口

概论

  • 方法在编译时静态绑定,依托于具体的类型
  • 接口对应的方法是在运行时动态绑定
  • 进程内初始化顺序 初始化导入包的常量和变量(可以导出的变量)--->包的init函数,不同文件内顺序是未定义的, 同一文件调用顺序是定义顺序--->main包内的常量变量和init---->main函数

函数调用顺序图

函数

  • 可变数量的参数必须最后出现,本质是一个切片类型的参数

  • 可变参数是一个空接口类型时,调用者是否解包可变参数会导致不同的结果

    • func main() {
      	var a = []interface{}{123, "abc"}
      
          Print(a...) // 123 abc 解包参数==》Print(123, "abc")
          Print(a)    // [123 abc] 不接包==》Print([]interface{}{123, "abc"})
      }
      
      func Print(a ...interface{}) {
      	fmt.Println(a...)
      }
      
    • 空接口类型:没有任何方法

  • 传参都是传值

    • append为什么必须有返回值:因为切片结构包含底层数组的指针, 长度和容量, 函数可以通过指针修改切片内容但是长度和容量无法修改,所以必须有返回值,带回被改变的长度和容量
  • 不用考虑堆栈位置,GC会自动设置变量存放位置

方法

  • 绑定在具体的类型,编译时静态绑定
  • 一个类型绑定的函数实现了接口的所有函数,这个类型就实现了这个接口
  • c实现的面向对象只用将相应的类型作为函数第一个参数传入
  • 没有传统面向对象的继承,通过组合来实现继承

接口

  • 接口可以实现虚函数的多态性,运行时确定,延迟绑定
  • 创建一个新的接口类型满足已经存在的具体类型而不用破坏这些类型的原有定义
  • 基础类型不支持隐士转换
  • 结构体内可以包含接口类型,纯虚函继承

空接口

  • 没有任何方式

  • 空接口内部实现保存了对象的类型和指针

  • 空接口可以保存任何对象,类似于一个集装箱,存放物品

    • // 声明a变量, 类型int, 初始值为1
      var a int = 1
      // 声明i变量, 类型为interface{}, 初始值为a, 此时i的值变为1
      var i interface{} = a
      // 声明b变量, 尝试赋值i
      var b int = i  //出错,因为i是接口类型的,也不能显示转化
      var i interface{} = 5667
      j := i.(int)
      fmt.Printf("%T->%d
      ", j, j) //使用类型断言来转换,不安全的转化
      
  • 空接口比较:类型和指针比较, 两个都一样才一样;

  • 不能比较空接口中的动态值

类 型 说 明
map 宕机错误,不可比较
切片([]T) 宕机错误,不可比较
通道(channel) 可比较,必须由同一个 make 生成,也就是同一个通道才会是 true,否则为 false
数组([容量]T) 可比较,编译期知道两个数组是否一致
结构体 可比较,可以逐个比较结构体的值
函数 可比较

类型断言

  • x.(T) x是interface()类型, T是要断言的类型
  • 使用场景:当某个interface{}的变量真是类型为A时才做某件事
  • 相当于赋值给void*的真实类型
原文地址:https://www.cnblogs.com/sfth/p/10744654.html