前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go语言学习之接口与动态类型

go语言学习之接口与动态类型

作者头像
张宗伟 plus
发布2023-01-04 14:07:58
3270
发布2023-01-04 14:07:58
举报
文章被收录于专栏:张宗伟 plus张宗伟 plus

本学习笔记全部以代码块的形式展示,具体的内容都包含在代码里:

代码语言:javascript
复制
package types

import (
  "errors"
  "fmt"
  "reflect"
)

// 接口与动态类型
// 1. interface{}(空接口) 可以当作泛型使用,可以接受任何go类型(个人理解)。
// 2. Go 没有类,数据(结构体或更一般的类型)和方法是一种松耦合的正交关系。
// 3. 接口需要提供一个指定方法集的实现,任何提供了接口方法实现代码的类型都隐式地实现了该接口,而不用显式地声明。
// 4. Go 是唯一结合了接口值,静态类型检查(是否该类型实现了某个接口),运行时动态转换的语言。(js没有静态检查真是永远的痛!)
// 5. Go 也拥有动态类型,即 duck typing(看起来像鸭子,那么就是鸭子),实现某个接口的类型可以作为实参传递给以该接口为形参的函数,并且还提供了静态检查。
// 6. 一个类型可以实现多个接口。
// 7. Go 使用可变参数间接实现 函数重载。
// 8. Go 中的接口也可以实现 继承,即当一个类型包含(内嵌)另一个类型(实现了一个或多个接口)的指针时,这个类型就可以使用(另一个类型)所有的接口方法。

// 3
type Person interface {
  getName() string
  getAge() int
}

type P struct {
  name   string
  age    int
  career string
}

// 结构体 P 实现了 Person 接口
func (p P) getName() string {
  return p.name
}
func (p P) getAge() int {
  return p.age
}

// 5
func getPerson(p Person) (name string, age int) {
  name = p.getName()
  age = p.getAge()
  return name, age
}

// 6
// 再声明 Worker 接口
type Worker interface {
  getCareer() string
}

func (p P) getCareer() string {
  return p.career
}

// 8
type Chinese struct {
  nation string
  P
}

func InterfaceAndDynamic() {
  var p1 P = P{"zdzw", 27, "front_end engineer"}

  p1_name, p1_age := getPerson(p1)

  fmt.Printf("p1_name: %s, p1_age: %d, p1_career: %s\n", p1_name, p1_age, p1.getCareer())

  var c1 Chinese = Chinese{"China", p1}

  fmt.Printf("c1_nation: %s, c1_career: %s\n", c1.nation, c1.getCareer())

  // 练习
  map_function(1, 2, 3, "aaa", "bbb", "ccc")
  stack_function()
}
// 实现可接口任意类型作为参数的函数,是 int 则双倍;是 string 则自身相加。
func map_function(args ...interface{}) {
  var result []interface{}
  for _, val := range args {
    t := reflect.TypeOf(val)
    v := reflect.ValueOf(val)
    switch t.Kind() {
    case reflect.Int:
      result = append(result, v.Int()*2)
    case reflect.String:
      result = append(result, v.String()+v.String())
    default:
    }
  }
  fmt.Println("map_function: ", result)
}

// 实现一个可以接受任何类型的栈
type Stack interface {
  Len() int
  IsEmpty() bool
  push(x interface{})
  pop() (interface{}, error)
  Top() (interface{}, error)
}

type StackIns []interface{}

func (s StackIns) Len() int {
  return len(s)
}

func (s StackIns) IsEmpty() bool {
  return s.Len() <= 0
}

func (s *StackIns) Push(x interface{}) {
  *s = append(*s, x)
}

func (s *StackIns) Pop() (interface{}, error) {
  s_val := *s
  if len(s_val) == 0 {
    return nil, errors.New("stack is empty")
  }
  v := s_val[len(s_val)-1]
  *s = s_val[:len(s_val)-1]
  return v, nil
}

func (s StackIns) Top() (interface{}, error) {
  if len(s) == 0 {
    return nil, errors.New("stack is empty")
  }
  return s[len(s)-1], nil
}

func stack_function() {
  var s StackIns = StackIns{1, 2, 3, "a", "b", "c"}
  s.Push("d")
  fmt.Println("s.Push: ", s, len(s))
  v, _ := s.Top()
  fmt.Println("s.Top: ", v)
  v, _ = s.Pop()
  fmt.Println("s.Pop: ", v, s)
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 张宗伟 plus 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档