Golang接口类型的动态类型和动态值学习理解

        在Golang中一个接口由两个部分组成,分别是动态类型和动态值。在一个时刻,一个接口只能有一个类型和值,这是这个接口该时刻的具体类型和具体值。因为一个接口可以有多个结构体实现,所以当不同的实现该接口的结构体赋值给一个接口变量的时候,接口的动态类型会变成该结构体类型,接口内部存储的指向结构体的指针会指向当前赋值的结构体,而动态值会变成当前赋值的结构体的值。

        例如 
       

type Shape interface {
	Area() float64
}
type Circle struct {
	Radius float64
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

type Rectangle struct {
	Width  float64
	Height float64
}

func (r Rectangle) Area() float64 {
	return r.Width * r.Height
}

        上述代码中 Circle结构体和Rectangle 结构体分别实现了Shape接口

func main(){
    var s Shape
	println("第一次赋值")
	s = Circle{4.1}
    println("第二次赋值")
	s = Rectangle{Width: 3.3, Height: 4.4}
}

         然后我们分别为其两次赋值,第一次赋值的时候动态类型为main.Circle,动态值为{4.1};第二次赋值动态类型为main.Rectangle,动态值为{3.3,4.4}。

        赋值之后因为s类型为Shape,我们无法调用其动态类型变量的动态值如无法通过

var shape Shape
s = Circle{4.1}
s.Radius 

,这时候就需要用到断言来判断并将接口变量转换为具体的类型。

示例代码如下:

package main

import (
	"fmt"
	"math"
)

func main() {
	var s Shape
	println("第一次赋值")
	s = Circle{4.1}
	v, ok := s.(Circle)
	if ok {
		v1 := v.Radius
		fmt.Printf("s的动态类型为%T\n这取出s的半径为%f\n", v, v1)
		fmt.Println("动态值为", v)
		fmt.Println("面积为", v.Area())
	}
	println("第二次赋值")
	s = Rectangle{Width: 3.3, Height: 4.4}
	va, ok := s.(Rectangle)
	if ok {
		v1 := va.Width
		v2 := va.Height
		fmt.Printf("s的动态类型为%T\n宽为%f\n高未%f\n", va, v1, v2)
		fmt.Println("动态值为", va)
		fmt.Println("面积为", va.Area())
	}
}

type Shape interface {
	Area() float64
}
type Circle struct {
	Radius float64
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

type Rectangle struct {
	Width  float64
	Height float64
}

func (r Rectangle) Area() float64 {
	return r.Width * r.Height
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值