0

0

go语言接口类型怎么转换

青灯夜游

青灯夜游

发布时间:2023-01-11 11:41:51

|

2119人浏览过

|

来源于php中文网

原创

go语言可利用类型断言来进行接口类型。在go中,无论是将一个接口类型转换成另一个接口类型,还是将一个接口转换为另一个基本类型,都必须需要使用 类型断言;转换语法有两种“转换后的变量 := 接口变量.(目标类型)”和“转换后的变量 , ok := 接口变量.(目标类型)”。

go语言接口类型怎么转换

本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。

在 Golang 中,将一个 接口 类型转换成另一个接口 类型,或者将一个接口转换为另一个基本类型,都必须需要使用 类型断言

类型断言的格式

类型断言是一个使用在接口值上的操作。语法上它看起来像 i.(T) 被称为断言类型,这里 i 表示一个接口的类型和 T 表示一个类型。一个类型断言检查它操作对象的动态类型是否和断言的类型匹配。

立即学习go语言免费学习笔记(深入)”;

类型断言的基本格式如下:

t := i.(T)

其中,i 代表接口变量,T 代表转换的目标类型,t 代表转换后的变量。

这里有两种可能。第一种,如果断言的类型 T 是一个具体类型,然后类型断言检查 i 的动态类型是否和 T 相同。如果这个检查成功了,类型断言的结果是 i 的动态值,当然它的类型是 T。换句话说,具体类型的类型断言从它的操作对象中获得具体的值。如果检查失败,接下来这个操作会抛出 panic。例如:

var w io.Writer
w = os.Stdout
f := w.(*os.File) // 成功: f == os.Stdout
c := w.(*bytes.Buffer) // 死机:接口保存*os.file,而不是*bytes.buffer

第二种,如果相反断言的类型 T 是一个接口类型,然后类型断言检查是否 i 的动态类型满足 T。如果这个检查成功了,动态值没有获取到;这个结果仍然是一个有相同类型和值部分的接口值,但是结果有类型 T。换句话说,对一个接口类型的类型断言改变了类型的表述方式,改变了可以获取的方法集合(通常更大),但是它保护了接口值内部的动态类型和值的部分。

在下面的第一个类型断言后,w 和 rw 都持有 os.Stdout 因此它们每个有一个动态类型 *os.File,但是变量 w 是一个 io.Writer 类型只对外公开出文件的 Write 方法,然而 rw 变量也只公开它的 Read 方法。

var w io.Writer
w = os.Stdout
rw := w.(io.ReadWriter) // 成功:*os.file具有读写功能
w = new(ByteCounter)
rw = w.(io.ReadWriter) // 死机:*字节计数器没有读取方法

如果断言操作的对象是一个 nil 接口值,那么不论被断言的类型是什么这个类型断言都会失败。几乎不需要对一个更少限制性的接口类型(更少的方法集合)做断言,因为它表现的就像赋值操作一样,除了对于 nil 接口值的情况。

如果 i 没有完全实现 T 接口的方法,这个语句将会触发宕机。触发宕机不是很友好,因此上面的语句还有一种写法:

t,ok := i.(T)

这种写法下,如果发生接口未实现时,将会把 ok 置为 false,t 置为 T 类型的 0 值。正常实现时,ok 为 true。这里 ok 可以被认为是:i 接口是否实现 T 类型的结果。

将接口转换为其他接口

实现某个接口的类型同时实现了另外一个接口,此时可以在两个接口间转换。

鸟和猪具有不同的特性,鸟可以飞,猪不能飞,但两种动物都可以行走。如果使用结构体实现鸟和猪,让它们具备自己特性的 Fly() 和 Walk() 方法就让鸟和猪各自实现了飞行动物接口(Flyer)和行走动物接口(Walker)。

将鸟和猪的实例创建后,被保存到 interface{} 类型的 map 中。interface{} 类型表示空接口,意思就是这种接口可以保存为任意类型。对保存有鸟或猪的实例的 interface{} 变量进行断言操作,如果断言对象是断言指定的类型,则返回转换为断言对象类型的接口;如果不是指定的断言类型时,断言的第二个参数将返回 false。

例如下面的代码:

var obj interface = new(bird)
f, isFlyer := obj.(Flyer)

代码中,new(bird) 产生 *bird 类型的 bird 实例,这个实例被保存在 interface{} 类型的 obj 变量中。使用 obj.(Flyer) 类型断言,将 obj 转换为 Flyer 接口。f 为转换成功时的 Flyer 接口类型,isFlyer 表示是否转换成功,类型就是 bool。

下面是详细的代码(代码1):

package main
import "fmt"
// 定义飞行动物接口
type Flyer interface {
    Fly()
}
// 定义行走动物接口
type Walker interface {
    Walk()
}
// 定义鸟类
type bird struct {
}
// 实现飞行动物接口
func (b *bird) Fly() {
    fmt.Println("bird: fly")
}
// 为鸟添加Walk()方法, 实现行走动物接口
func (b *bird) Walk() {
    fmt.Println("bird: walk")
}
// 定义猪
type pig struct {
}
// 为猪添加Walk()方法, 实现行走动物接口
func (p *pig) Walk() {
    fmt.Println("pig: walk")
}
func main() {
// 创建动物的名字到实例的映射
    animals := map[string]interface{}{
        "bird": new(bird),
        "pig":  new(pig),
    }
    // 遍历映射
    for name, obj := range animals {
        // 判断对象是否为飞行动物
        f, isFlyer := obj.(Flyer)
        // 判断对象是否为行走动物
        w, isWalker := obj.(Walker)
        fmt.Printf("name: %s isFlyer: %v isWalker: %v\n", name, isFlyer, isWalker)
        // 如果是飞行动物则调用飞行动物接口
        if isFlyer {
            f.Fly()
        }
        // 如果是行走动物则调用行走动物接口
        if isWalker {
            w.Walk()
        }
    }
}

代码说明如下:

  • 第 6 行定义了飞行动物的接口。

  • 第 11 行定义了行走动物的接口。

    网奇企业网站管理系统CWMS2.0 英文版
    网奇企业网站管理系统CWMS2.0 英文版

    CWMS 2.0功能介绍:一、 员工考勤系统,国内首创CWMS2.0的企业员工在线考勤系统。二、 自定义URL Rewrite重写,友好的搜索引擎 URL优化。三、 代码与模板分离技术,支持超过5种类型的模板类型。包括:文章、图文、产品、单页、留言板。四、 购物车功能,CWMS2.0集成国内主流支付接口。如:淘宝、易趣、快钱等。完全可媲美专业网上商城系统。五、 多语言自动切换 中英文的说明。六、

    下载
  • 第 16 和 30 行分别定义了鸟和猪两个对象,并分别实现了飞行动物和行走动物接口。

  • 第 41 行是一个 map,映射对象名字和对象实例,实例是鸟和猪。

  • 第 47 行开始遍历 map,obj 为 interface{} 接口类型。

  • 第 50 行中,使用类型断言获得 f,类型为 Flyer 及 isFlyer 的断言成功的判定。

  • 第 52 行中,使用类型断言获得 w,类型为 Walker 及 isWalker 的断言成功的判定。

  • 第 57 和 62 行,根据飞行动物和行走动物两者是否断言成功,调用其接口。

代码输出如下:

1.png

将接口转换为其他类型

在代码 1 中,可以实现将接口转换为普通的指针类型。例如将 Walker 接口转换为 *pig 类型,请参考下面的代码:

p1 := new(pig)
var a Walker = p1
p2 := a.(*pig)
fmt.Printf("p1=%p p2=%p", p1, p2)

对代码的说明如下:

  • 第 3 行,由于 pig 实现了 Walker 接口,因此可以被隐式转换为 Walker 接口类型保存于 a 中。

  • 第 4 行,由于 a 中保存的本来就是 *pig 本体,因此可以转换为 *pig 类型。

  • 第 6 行,对比发现,p1 和 p2 指针是相同的。

如果尝试将上面这段代码中的 Walker 类型的 a 转换为 *bird 类型,将会发出运行时错误,请参考下面的代码:

p1 := new(pig)
var a Walker = p1
p2 := a.(*bird)

运行时报错:

panic: interface conversion: main.Walker is *main.pig, not *main.bird

报错意思是:接口转换时,main.Walker 接口的内部保存的是 *main.pig,而不是 *main.bird。

因此,接口在转换为其他类型时,接口内保存的实例对应的类型指针,必须是要转换的对应的类型指针。

总结

接口和其他类型的转换可以在Go语言中自由进行,前提是已经完全实现。

接口断言类似于流程控制中的 if。但大量类型断言出现时,应使用更为高效的类型分支 switch 特性。

【相关推荐:Go视频教程编程教学

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

1

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

21

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

106

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

50

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

87

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

27

2026.03.03

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

79

2026.02.28

Golang 工程化架构设计:可维护与可演进系统构建
Golang 工程化架构设计:可维护与可演进系统构建

Go语言工程化架构设计专注于构建高可维护性、可演进的企业级系统。本专题深入探讨Go项目的目录结构设计、模块划分、依赖管理等核心架构原则,涵盖微服务架构、领域驱动设计(DDD)在Go中的实践应用。通过实战案例解析接口抽象、错误处理、配置管理、日志监控等关键工程化技术,帮助开发者掌握构建稳定、可扩展Go应用的最佳实践方法。

61

2026.02.28

Golang 性能分析与运行时机制:构建高性能程序
Golang 性能分析与运行时机制:构建高性能程序

Go语言以其高效的并发模型和优异的性能表现广泛应用于高并发、高性能场景。其运行时机制包括 Goroutine 调度、内存管理、垃圾回收等方面,深入理解这些机制有助于编写更高效稳定的程序。本专题将系统讲解 Golang 的性能分析工具使用、常见性能瓶颈定位及优化策略,并结合实际案例剖析 Go 程序的运行时行为,帮助开发者掌握构建高性能应用的关键技能。

50

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 6.6万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 4.2万人学习

Go 教程
Go 教程

共32课时 | 5.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号