写点什么

Go 类型转换和类型断言可别搞混了

作者:王中阳Go
  • 2022-11-18
    北京
  • 本文字数:2576 字

    阅读完需:约 8 分钟

Go类型转换和类型断言可别搞混了

这篇文章汇总了我在开发和刷题过程中遇到的容易搞错的知识点,关键部分也都为大家写了代码示例。


每个知识点都手撸代码进行了验证,确保内容的准确性。


我整理的《Go 语言学习路线图》 已经被 540 多位小伙伴关注,想系统学习 Go 语言的小伙伴可以关注一下,硬核原创内容持续更新中。

类型转换和类型断言

类型转换语法:Type(expression)


类型断言语法为:expression.(Type)

1.类型转换示例代码

package main
import "fmt"
//典型的类型转换示例func main() { // 类型转换示例 var a int = 5 var b int = 2 var c float32 c = float32(a) / float32(b) //这里就是典型的类型转换 fmt.Printf("a的类型:%T\n", a) fmt.Printf("b的类型:%T\n", b) fmt.Printf("c的类型:%T\n", c) fmt.Printf("c的值:%v\n", c) //如果我们不进行类型转换,看下输出结果 fmt.Printf("不进行类型转换的输出结果:%v\n", a/b) //从结果可以看出值为2,丢失了精度}
复制代码

打印结果

2.类型断言代码示例

注意:对于类型断言,expression 必须是接口类型


package main
import "fmt"
//经典的类型断言示例 搭配switch使用func main() { var x interface{} x = 1 switch x.(type) { //这就是上面说的expression.(Type) case float32: fmt.Println("类型是:float32") case string: fmt.Println("类型是:string") case int: fmt.Println("类型是:int") default: fmt.Println("未知类型") }}
复制代码

运行结果

全局变量

定义全局变量必须用 var,全局变量要定义在函数之外,而在函数之外定义的变量只能用 var 定义。

全局变量使用 var,编译通过

全局变量不使用 var,编译不通过

init 函数

这是官方对于 init()函数的介绍:


变量除了可以在全局声明中初始化,也可以在 init ()函数中初始化。这是一类非常特殊的函数,它不能够被人为调用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性。


如何觉得上面这一大段话不好理解的话,可以看我的总结:


  1. init 函数可以在任何包中有 0 个、1 个或多个;

  2. main 函数只能在 main 包中有且只有一个,但是 main 包中也可以有 0 个、1 个或多个 init 函数;

  3. init 函数和 main 函数都不能被显式调用;

Go 语言中变量、init 函数、main 函数的执行顺序

  1. 首先初始化导入包的变量和常量

  2. 然后执行导入包的 init 函数

  3. 然后初始化本包的变量和常量

  4. 然后执行本包的 init 函数

  5. 最后执行本包的 main 函数

Go 接口总结

这是我在刷题的时候碰到的,总结出来给大家:


  1. 如果两个接口拥有相同方法列表(顺序可以不一致),那么这两个接口实质上同一个接口

  2. 接口 A 是接口 B 的子集,意味着 A 的方法 B 中都有,那么 A 是 B 的基类,所以 A=B 是可行的

  3. 接口是否能够调用成功,需要运行的时候才能知道

  4. 接口赋值是否可行,在编译阶段就可以知道

Go 字符串

Go 语言中的字符串不支持下标操作



在 go 语言中,字符串是一种基本类型,和其它开发语言不同,Go 的字符串是由单个字节连接起来的。


Go 语言统一使用 utf-8 编码标识 Unicode 文本。当字符为 ASCII 编码时,占用 1 个字节,其它字符占用 2 到 4 个字节,中文占用 3 个字节

如何修改字符串的内容呢?

有三种方法:


  1. 将字符串转成 byte 切片,再根据下标替换内容

  2. 将字符串转为 rune 切片,再根据下标替换内容

  3. 使用原生包 strings 中的 Replace() 方法

示例代码

package main
import ( "fmt" "strings")
func main() { //第一种方法 将字符串转成byte切片 s := "hello" s2 := []byte(s) s2[0] = 'x' fmt.Printf("转成byte切片:%v\n", string(s2)) //打印结果:转成byte切片:xello
// 第二种方法 将字符串转为rune切片 s3 := "王中阳" s4 := []rune(s3) //注意:中文字符串要进行修改,只能转成rune切片,不能转成byte切片 s4[0] = '杨' fmt.Printf("转成rune切片:%v\n", string(s4)) //打印结果:转成rune切片:杨中阳
// 第三种方法,使用原生包strings 中的 Replace() 方法 s5 := "abcdef" old := "abc" newString := "ABC" s6 := strings.Replace(s5, old, newString, -1) //最后一个参数n的作用是:返回将s5中前n个不重叠old子串都替换为new的新字符串,如果n<0会替换所有old子串。 fmt.Printf("strings替换之后的:%v\n", s6) //打印结果:strings替换之后的:ABCdef}
复制代码

运行结果

slice

slice 可以通过 append 方式实现元素的删除。


**切片使用冒号分隔时遵循"前闭后开"原则,即包括前面的值,不包括后面的值。**

1.删除单个元素

package main
import "fmt"
//使用append 删除单个元素func main() { var data = []int{0, 1, 2, 3, 4, 5} //删除元素2 index := 2 //切片使用冒号分隔时遵循"前闭后开"原则,即包括前面的值,不包括后面的值。 data1 := append(data[:index], data[index+1:]...) fmt.Println(data1)}
复制代码

运行结果

2.删除多个元素

package main
import "fmt"
//使用append 删除多个元素func main() { var data = []int{0, 1, 2, 3, 4, 5} //删除元素0,1,2 index := 2 //切片使用冒号分隔时遵循"前闭后开"原则,即包括前面的值,不包括后面的值。 data1 := append(data[:0], data[index+1:]...) fmt.Println(data1)}
复制代码

运行结果

总结

这篇文章汇总了我在开发和刷面试题过程中遇到的容易搞错的知识点,包括:


  1. 类型转换和类型断言的对比

  2. 定义全局变量只能用 var,定义全局变量也可以定义在 init()函数中

  3. init()函数的知识点,以及 init 函数和 main 函数的执行顺序:先执行引用包的常量和变量、在执行引用包的 init 函数、再执行本包的常量和变量、再执行本包的 init 函数、最后才会执行本包的 main 函数。

  4. Go 接口的概念总结,刷面试题的时候可能碰到咬文嚼字的问题,注意避坑。

  5. Go 字符串不能通过下标直接修改内容,但是可以通过转成 byte[]/rune[]/以及使用原生包 strings 中的 Replace()方法修改内容

  6. Go 中的 slice 不能像 map 一样直接使用 delete()方法删除元素,可以使用 append()方法+冒号分隔切片的方式,间接实现切片元素的删除。


好了,今天的内容就到这里,关注我,持续更新硬核内容。


一起学习

欢迎和我们一起学 Go,坚持打卡,互相监督。


可以通过下面「作者栏」的信息联系我加群,一起学习。

发布于: 2022-11-18阅读数: 47
用户头像

王中阳Go

关注

靠敲代码在北京买房的程序员 2022-10-09 加入

公众号:程序员升级打怪之旅👍微信:wangzhongyang1993👍InfoQ优质创作者👍掘金签约作者👍B站&掘金&CSDN&思否等全平台账号:王中阳Go

评论 (1 条评论)

发布
用户头像
这篇文章汇总了我在开发和刷题过程中遇到的容易搞错的知识点,关键部分也都为大家写了代码示例。
2022-11-18 11:20 · 北京
回复
没有更多了
Go类型转换和类型断言可别搞混了_golang_王中阳Go_InfoQ写作社区