写点什么

Go- 接口 -1

用户头像
HelloBug
关注
发布于: 3 小时前
Go- 接口-1

Go 学习笔记,学习内容《Go入门指南》


主要介绍以下内容:

  • 接口类型的定义

  • 接口赋值

  • 接口数组

  • 接口嵌套

  • 接口变量类型-var.(T)

  • 接口变量类型-type-switch

  • 如何获得各种变量的类型


代码示例可以直接运行

package main
import ( "fmt" "reflect")
func printDivider(str ...string) { fmt.Println() fmt.Println("-----------------------------------------------") if len(str) > 0 { fmt.Println(str) }}
type Shaper interface { // 接口名称使用er结尾 Area() float32}
type Square struct { side float32}
func (sq *Square) Area() float32 { // 实现接口的方法 return sq.side * sq.side}
type Circular struct { redius float32}
func (cir *Circular) Area() float32 { return 3.14 * cir.redius * cir.redius}
func (cir *Circular) Perimeter() float32 { return 2 * 3.14 * cir.redius}
type Color interface { Rgb() string}
type Object interface { Color Shaper}
type Paper struct { redius float32 color string}
func (p *Paper) Area() float32 { return 3.14 * p.redius * p.redius}
func (p *Paper) Rgb() string { return p.color + "." + p.color + "." + p.color}
func main() { /* 接口类型的定义 接口定义一组方法接口,仅声明方法,不实现方法。通常定义0-3个方法 接口中不能包含变量 接口名字通常使用(e)r结尾,如Reader、Writer、Logger等 一个类型可以实现多个接口 */ printDivider("接口类型的定义") sq1 := new(Square) sq1.side = 2 var areaIntf Shaper areaIntf = sq1 // sq1必须是一个指针,不能是一个实例 fmt.Println(areaIntf.Area()) // 输出:4
/* 接口赋值 必须实现接口的方法才可以对接口类型进行赋值 */ printDivider("接口赋值") rd1 := new(Circular) rd1.redius = 1.2 //若接口体Circular没有实现 Shaper 接口的 Area方法 //areaIntf = rd1 // 编译错误:cannot use rd1 (type *Circular) as type Shaper in assignment: *Circular does not implement Shaper (missing Area method)
// 结构体Circular除了Area方法,也可以实现其他方法 areaIntf = rd1 fmt.Println(areaIntf.Area()) //fmt.Println(areaIntf.Perimeter()) 编译错误:areaIntf.Perimeter undefined (type Shaper has no field or method Perimeter)
/* 接口数组 */ printDivider("接口数组") sq2 := &Square{5} rd2 := &Circular{2} shapes := []Shaper{sq2, rd2} for n, _ := range shapes { fmt.Println("Sharper details: ", shapes[n]) fmt.Println("Sharper Area: ", shapes[n].Area()) } /* 输出: Sharper details: &{5} Sharper Area: 25 Sharper details: &{2} Sharper Area: 12.56 */
/* 接口嵌套 */ printDivider("接口嵌套") p1 := &Paper{3, "255"} //var obj1 Object obj1 := p1 fmt.Println(obj1.Area()) // 输出:28.26 fmt.Println(obj1.Rgb()) // 输出:255.255.255
/* 接口变量类型-var.(T) */ printDivider("接口变量类型-var.(T)") if t, ok := shapes[0].(*Square); ok { fmt.Printf("The TYpe of shapes[0] is : %T\n", t) // 输出:The TYpe of shapes[0] is : *main.Square }
if t, ok := shapes[1].(*Circular); ok { fmt.Printf("The Type of shapes[1] is : %T\n", t) // 输出:The Type of shapes[1] is : *main.Circular }
/* 接口变量类型-type-switch */ printDivider("接口变量类型-type-switch") switch t := areaIntf.(type) { case *Square: fmt.Printf("Type Square %T with value %v\n", t, t) // 输出:Type Circular *main.Circular with value &{1.2} case *Circular: fmt.Printf("Type Circular %T with value %v\n", t, t) default: fmt.Printf("I don not know who you are.") }
/* 如何获得各种变量的类型 */ printDivider("如何获得各种变量的类型") classifier(1, 2) classifier("a", 100)
/* var.(Type)只能用于简单数据类型,不能用于array, slice, map */ //var x1 [5]string //fmt.Println(x1.(Type)) // 编译错误:invalid type assertion: x1.(Type) (non-interface type [5]string on left) x2 := []int{1, 2, 3} fmt.Printf("Type: %T\n", x2) // 输出:Type: []int
t := reflect.TypeOf(x2).String() // 可以使用reflect.TypeOf判断array, slice, map的类型 if t == "[]int" { fmt.Println("TypeOf: []int") // 输出: TypeOf: []int }
x3 := x2[:2] fmt.Printf("Type: %T\n", x3) // 输出:Type: []int t = reflect.TypeOf(x3).String() // 可以使用reflect.TypeOf判断array, slice, map的类型 if t == "[]int" { fmt.Println("TypeOf: []int") // 输出: TypeOf: []int }
x4 := map[string]string{"a": "1", "b": "2", "c": "3"} fmt.Printf("Type: %T\n", x4) // 输出:Type: map[string]string t = reflect.TypeOf(x4).String() // 可以使用reflect.TypeOf判断array, slice, map的类型 if t == "map[string]string" { fmt.Println("TypeOf: map[string]string") // 输出:TypeOf: map[string]string }
/* 测试值是否实现某个接口? */}
/* 类型分类函数,可变参数,item是一个数组,数组里的元素可以是不同的类型*/func classifier(items ...interface{}) { for i, x := range items { switch x.(type) { case bool: { fmt.Printf("Param #%d is a bool\n", i) } case int, int64: { fmt.Printf("Param #%d is a int\n", i) } case float32, float64: { fmt.Printf("Param #%d is a float\n", i) } case string: { fmt.Printf("Param #%d is a string\n", i) } case nil: { fmt.Printf("Param #%d is a nil\n", i) } default: { fmt.Printf("Param #%d is x\n", i) } } }}
复制代码


发布于: 3 小时前阅读数: 3
用户头像

HelloBug

关注

还未添加个人签名 2018.09.20 加入

还未添加个人简介

评论

发布
暂无评论
Go- 接口-1