本学习笔记全部以代码块的形式展示,具体的内容都包含在代码里:
代码语言: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: %sn", p1_name, p1_age, p1.getCareer())
var c1 Chinese = Chinese{"China", p1}
fmt.Printf("c1_nation: %s, c1_career: %sn", 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)
}