首页 > 其他分享 >下篇:一文玩转Go接口

下篇:一文玩转Go接口

时间:2022-10-26 23:23:33浏览次数:74  
标签:下篇 int fmt value interface 玩转 func Go main

  1. 空接口既然可以存储任意类型的值,那么从空接口获取到的值是否可以直接使用?看下面栗子
package main

import (
 "fmt"
)

var a interface{}
var b interface{}

func main() {
 a = 1024
 b = 100
 res := a + b
 fmt.Println(res)
}

报错:

invalid operation: operator + not defined on a (variable of type interface{}) (exit status 2)

程序报错的原因:因为空接口的类型是不可以直接使用的,需要警告类型断言转换方可使用。

  1. 这次我们使用类型断言来将接口类型转成int类型
package main

import (
 "fmt"
)

var a interface{}
var b interface{}

func main() {
 a = 1024
 b = 100
 val1, res1 := a.(int)
 fmt.Println(val1, res1)

 val2, res2 := b.(int)
 fmt.Println(val2, res2)

 //val1和val2接收转换后的值,res1和res2是类型断言的状态(成功或失败),断言成功是true,反之false
}

输出:

1024 true
100 true
  1. 类型断言新姿势:当使用一个值接受断言结果时,则会直接返回断言后的值
package main

import (
 "fmt"
)

var a interface{}
var b interface{}

func main() {
 a = 1024
 b = 100
    //类型断言转换
 a1 := a.(int)
 b1 := b.(int)
    //转换后进行相加,就不会报错了
 res := a1 + b1
 fmt.Println(res)

}
  1. 体会一下使用类型断言转换失败的快感
package main

import (
 "fmt"
 "log"
)

var a interface{}

func main() {
 a = 1024
 if a1, r := a.(string); r {
  fmt.Println(a1)
 } else {
  log.Fatalln("类型断言转换失败")
 }
}

输出:

2022/10/25 10:30:48 类型断言转换失败

变量a存储值是整型,视图使用类型断言将其转换为字符串,结果报错了,这么玩是不行的,玩不起。

  1. 类型断言+switch实现数据类型判断
package main

import (
 "fmt"
)

func TestFunc(value interface{}) {
 switch value.(type) {
 case int:
  fmt.Printf("value=%v Type Int\n", value)
 case float32:
  fmt.Printf("value=%v Type Float32\n", value)
 case float64:
  fmt.Printf("value=%v Type Float64\n", value)
 case string:
  fmt.Printf("value=%v Type string\n", value)
 }
}

func main() {
 TestFunc("hello")
 TestFunc(100)
 TestFunc(89.12)
}

输出:

value=hello Type string
value=100 Type Int
value=89.12 Type Float64
  1. 还可以将接口类型转换成另一个接口类型,下面的栗子是将A接口转换成B接口
package main

import (
 "fmt"
)

type A interface{}

type B interface{}

func main() {
 var a A = 100
 b := a.(B)
 fmt.Println(b)
}

在之前的栗子,都是将接口类型转换成基本的数据类型,而这个栗子是将一个自定义的接口类型转换成另一个自定义的接口类型。

  1. 还可以将接口类型转成指针类型,看下面的栗子
package main

import "fmt"

func main() {
    //定义接口类型的变量ainter
 var ainter interface{}
 num := 100
 ainter = &num //将地址赋给接口变量

 v, r := ainter.(*int)
 fmt.Println(v, r)
}

上面的栗子中,使用类型断言将接口类型转成了int指针类型

  1. 接口可以嵌套吗?实战告诉你
package main

import "fmt"

type action1 interface {
 insert()
}

type action2 interface {
 delete()
}

type actionInterface interface {
 action1
 action2
 query()
}

type Db struct {
 Data string
}

func (d Db) insert() {
 fmt.Print("插入数据...", d.Data)
}

func (d Db) delete() {
 fmt.Print("删除数据...", d.Data)
}

func (d Db) query() {
 fmt.Print("查询数据...", d.Data)
}

func main() {
 d := Db{Data: "hello"}
 d.query()
 d.delete()
 d.insert()
}

通过上面的实战,接口是可以嵌套的,注意了,只有实现接口中所有的方法(含所有嵌套接口里的所有方法),那么才算是真正实现了接口。

  1. 实现error接口中的Error方法,来玩一个自定义错误类型的栗子
package main

import (
 "fmt"
)

type AddError struct {
 ErrorMsg string
}

func (m AddError) Error() string {
 return fmt.Sprintf("Add error %v", m.ErrorMsg)
}

func add(a int, b int) (int, error) {
 if a == 0 || b == 0 {
  errinfo := fmt.Sprintf("a=%v, b=%v", a, b)
  return 0, AddError{ErrorMsg: errinfo}
 } else {
  return a + b, nil
 }
}

func main() {
 res, err := add(8, 0)
 fmt.Println(res, err)
}

上面的栗子中,已经隐式的实现了error接口中的Error方法

  1. 如果不玩自定义的错误类型,也可以直接使用errors.New方法返回一个错误信息
package main

import (
 "errors"
 "fmt"
)

func add(a int, b int) (int, error) {
 if a == 0 || b == 0 {
  return 0, errors.New("不能为0")
 } else {
  return a + b, nil
 }
}

func main() {
 res, err := add(9, 1)
 fmt.Println(res, err)
}

本文转载于(喜欢的盆友关注我们):https://mp.weixin.qq.com/s/AcgyT9rfCsCsp1PWiEKimA

标签:下篇,int,fmt,value,interface,玩转,func,Go,main
From: https://www.cnblogs.com/ttropsstack/p/16830523.html

相关文章

  • Linux安装配置Go语言
    Linux安装配置Go语言官网:https://go.dev/dl/从官网下载,选择linux下载压缩包。sudocp-rgo//usr/localsudogedit/etc/profilesource/etc/profile验证......
  • 单调栈--Feel Good
    DescriptionBillisdevelopinganewmathematicaltheoryforhumanemotions.Hisrecentinvestigationsarededicatedtostudyinghowgoodorbaddaysinfluentpe......
  • hyperf/go/springboot通过jsonrpc通信
    一、背景随着用户的增长和业务的增多,单节点服务已经满足不了需求,用hyperf对主业务进行了重构。hyperf是一个后现代的php框架,基于php+swoole,支持协程,解决了php让人诟病的......
  • Android开发页面重定向导致WebvView.canGoBack一直返回true的解决方法
    Android开发页面重定向导致WebvView.canGoBack一直返回true的解决方法原因:打开页面A的时候重定向到页面B,页面B回退的时候回退到页面A,但是接着又重定向到页面B,所以canGoB......
  • 03.Go语言环境安装——09.变量的初始化
    3.Go语言环境安装Go的下载Go的下载网址选择合适的版本进行下载安装完成,在cmd目录下,输入“goversion”检查版本Go的环境变量设置右击我的电脑——属性——高级系统......
  • HELM chart 部署mongodb 到k8s 集群 pod 无法解析dns 问题
    1,正常拉取bitbami的包部署mongodb到k8s集群,运行前一切正常2,部署到mongodb-1的时候,卡主,查看日志,arbiter报无法连接mongodb-0或者mongodb-headless 3,搜到早些年的issu......
  • 一条龙式搭建Hugo博客
    一条龙式搭建Hugo博客一条龙式搭建Hugo博客安装hugo使用hugo生成站点与文章,并在本地查看安装hugo主题,美化你的博客使用GitHub的pages功能发布你的网页注......
  • mongodb聚合分组返回最新一条和count distinct查询
    db.collection.aggregate([{$group:{"_id":"$city","unique_count":{$addToSet:"$zipcode"}......
  • 通过一个例子让你彻底掌握 Go 工作区模式
    通过一个例子让你彻底掌握Go工作区模式站长polaris Go语言中文网 2022-10-2608:52 发表于北京 阅读本文大概需要5分钟。大家好,我是polarisxu。早在Go1.18......
  • go 课程表
    目录课程表项目工程Demo简化版(一)课程表项目工程Demo简化版(一)描述:主要讲了cmdb的基础框架,结构体,后端api的构建,怎么读取配置文件,日志的库的使用等。还有比如http调用s......