Go 语言核心 36 讲
郝林
《Go 并发编程实战》作者,前轻松筹大数据负责人
79610 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
Go 语言核心 36 讲
15
15
1.0x
00:00/00:00
登录|注册

06 | 程序实体的那些事儿 (下)

[]rune类型转换
[]byte类型转换
UTF-8编码
Replacement Character
Unicode代码点
补码形式存储
合法转换范围
异常处理
结果赋给两个变量
赋值语句
语法形式
作用于代码重构过程中
值得注意的地方
类型转换、判等、比较和赋值操作
潜在类型
类型再定义
别名类型声明
string类型与切片类型互转
整数值转换为string类型值
整数类型值转换
类型断言表达式
别名类型
类型转换规则
别名类型与潜在类型
类型转换规则
变量类型判断
思考题
总结

该思维导图由 AI 生成,仅供参考

在上一篇文章,我们一直都在围绕着可重名变量,也就是不同代码块中的重名变量,进行了讨论。
还记得吗?最后我强调,如果可重名变量的类型不同,那么就需要引起我们的特别关注了,它们之间可能会存在“屏蔽”的现象。
必要时,我们需要严格地检查它们的类型,但是怎样检查呢?咱们现在就说。
我今天的问题是:怎样判断一个变量的类型?
我们依然以在上一篇文章中展示过的 demo11.go 为基础。
package main
import "fmt"
var container = []string{"zero", "one", "two"}
func main() {
container := map[int]string{0: "zero", 1: "one", 2: "two"}
fmt.Printf("The element is %q.\n", container[1])
}
那么,怎样在打印其中元素之前,正确判断变量container的类型?

典型回答

答案是使用“类型断言”表达式。具体怎么写呢?
value, ok := interface{}(container).([]string)
这里有一条赋值语句。在赋值符号的右边,是一个类型断言表达式。
它包括了用来把container变量的值转换为空接口值的interface{}(container)
以及一个用于判断前者的类型是否为切片类型 []string.([]string)
这个表达式的结果可以被赋给两个变量,在这里由valueok代表。变量ok是布尔(bool)类型的,它将代表类型判断的结果,truefalse
如果是true,那么被判断的值将会被自动转换为[]string类型的值,并赋给变量value,否则value将被赋予nil(即“空”)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了Go语言中的类型断言表达式的使用方法和注意事项。作者通过具体的示例代码和详细解析帮助读者理解了类型转换规则中的一些细节和技巧。文章重点强调了在使用类型转换表达式时需要注意的细节,如整数类型值、整数常量之间的转换规则、整数值转换为字符串类型值的注意事项,以及字符串类型与切片类型之间的互转规则。此外,文章还介绍了别名类型和潜在类型的概念,以及它们在代码重构过程中的作用。总的来说,本文通过深入的技术讨论帮助读者更好地理解Go语言中类型转换的规则和注意事项,适合对Go语言感兴趣的读者阅读。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 语言核心 36 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(46)

  • 最新
  • 精选
  • 思想的宇屋
    置顶
    真棒,这篇涉及到了自学go的gopher比较难涉及到的计算机基础和细节 如补码,类型转换异常时的“❓”
    2018-12-29
    15
  • NIXUS
    这节课,是从开始学习该专栏以来,最有价值的一节,没有之一! 希望剩下的课程,都能像这节课这样有价值!

    作者回复: 尽量做到能让大多数人满意:)

    2018-10-11
    2
    13
  • mkii
    type A struct { B *B } func (a *A) Print() { a.B.Print() } type B struct { str string } func (b *B) Print() { //if b.str == ""{ fmt.Println("1234") //}else{ // fmt.Println("str is:",b.str) //} } func TestAPrint(t *testing.T) { a := &A{nil} a.Print() } 老师,为什么print函数这里不会Panic呀?

    作者回复: 首先需要明确,结构体类型 A 中的字段 B(为了区分,以下称为 b 吧)的类型是一个“指针类型”,即 *B 。而结构体类型 B 携带了一个“指针方法” Print 。这里的“指针类型”和“指针方法”是关键。 即便 a 的字段 b 是 nil,但是 b 本身的“方法集合一直存在”(即类型 *B 的方法集合),只不过它的值为 nil 罢了。 正是由于 a 中的字段 b 的“方法集合一直存在”,因此a.b.Print() 这条链路才能走通。又由于类型 B 的方法 Print 的接收者类型为 *B ,所以在该方法执行的时候才不需要为了求接收者 b 的值而进行取值操作(即从 *B 到 B 的转换)。你可以想象一下,若 B 有另外一个方法 func (b B) Show() ,那么执行 a.b.Show() 会怎样。 你可以再写一些代码,如: var b1 *B = nil switch interface{}(b1).(type) { case C: fmt.Println("C") default: fmt.Println("?") } 执行这段代码会打印出“C”。那你觉得为什么Go编译器能够知道 interface{}(b1) 的类型是 C 呢?它就是根据 b1 的方法集合来判断的啊。 无论 b 和 b1 的值是什么,只要它们有类型,它们的方法集合就是固定的。它们的“方法集合一直存在”!

    2021-06-09
    8
  • 沐夜星光
    既然有了别名类型,为什么还要再搞个别名再定义,两者的应用场景有什么区别?

    作者回复: 两者都是为了隔离变化。 别名类型“另起炉灶”的只是名字,主要是向上层应用隐藏下层类型的真实名称。这样一来,下层类型体系在重构的时候就可以换名字了(不会影响到上层代码)。 类型再定义更彻底一些。主要是为了另外构建一个与潜在类型有所关联(有一定的互操作性)但又不同的类型。基于这个新类型,我们可以构建另外一套操作或者类型体系,而不用去改动潜在类型(或者说潜在类型所在的体系)。

    2020-01-06
    3
    7
  • 传说中的成大大
    一门新的技术的产生或者语言新特性的产生总是为了解决一些现有的比较棘手的问题 所以我在想 类型别名和 类型重定义及潜在类型 为什么会同时存在? 然后提到潜在类型 那么语言自带的类型 比如string是否有潜在类型 如果有是否就是它本身?

    作者回复: “类型别名”和“类型重定义”其实属于在Go语言的发展过程中相继出现的两个类似产物。但鉴于它们在功能上还是有明显差别的,所以理解起来也算容易。 “潜在类型”其实更多的是在语言词法分析方面起作用。从程序开发的角度讲,它几乎只与类型转换相关。“潜在类型”是Go语言规范中的死规定,所以记下来就好了。

    2020-03-02
    4
  • Hector
    string可以被称为MyString2的潜在类型,那他们的区别到底在哪里呢?底层时做的复制动作,但是指针存放的地址不同吗

    作者回复: 我在文章里说了:“潜在类型相同的不同类型的值之间是可以进行类型转换的”。这属于语法规则。 它们虽然代表着不同的类型,但本质上是同源的。也就是说,它们的底层结构是相同的。在这样情况下,在类型转换时值会被复制,即两个值会在不同的内存地址上。

    2019-05-10
    4
  • 扩散性百万咸面包
    其中的x可以是一个变量,也可以是一个代表值的字面量(比如1.23和struct{}{}),还可以是一个表达式。 struct{}{} 的意思是声明一个空结构然后立刻初始化?

    作者回复: 对, struct{} 是空结构体类型,struct{}{} 是对它的实例化。其实这种实例化总会返回相同的值。你可以把 struct{} 视为单例类型。

    2020-04-08
    3
  • 田佳伟
    首先你要知道,整数在 Go 语言以及计算机中都是以补码的形式存储的 这句话应该是:首先你要知道,负数在 Go 语言以及计算机中都是以补码的形式存储的 吧😄

    作者回复: 正数的补码等于其自身。

    2018-09-06
    3
  • 风一般的梦幻
    这一行:"其中的x可以是一个变量,也可以是一个代表值的字面量(比如1.23和struct{}),还可以是一个表达式。" 中的struct{}是否应改为struct{}{}?

    作者回复: 对的,我跟编辑说一下,谢谢。

    2019-10-28
    1
  • 影子传说
    类型再定义有什么好处?

    作者回复: 没有什么好处,是编码时需要注意和尽量避免的。

    2018-09-18
    2
    1
收起评论
显示
设置
留言
46
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部