写点什么

Go 语言学习查缺补漏 ing Day5

  • 2021 年 12 月 08 日
  • 本文字数:1416 字

    阅读完需:约 5 分钟

作者:ReganYue

来源:恒生LIGHT云社区

Go 语言学习查缺补漏 ing Day5

一、将切片当可变参数传递的一个问题

我们来看一段代码:


package main
import "fmt"
func Myfunc(num ...int) { num[0] = 2 total := 0 for _, i := range num { total += i } num[1] = total}func Sum(num ...int) {
total := 0 for _, i := range num { total += i } num[1] = total}func main() { i := []int{1, 2, 3} Myfunc(i...) fmt.Println(i) Sum(i...) fmt.Println(i)}
复制代码


这段代码的运行结果是:


[2 7 3][2 12 3]
复制代码


是不是很奇怪为什么切片内的值改变了?其实我们将切片作为函数参数传递给函数是进行的值传递,所以我们传递给函数的参数其实是下面这个 slice 的值拷贝。


type slice struct{    value *int     length uint     capacity uint }
复制代码


但是,这个 slice 结构体内的 value 是一个指针,所以这个 slice 就算进行了拷贝,它和它的拷贝值都是同一个 value,指向同一块区域。


所以上面的代码,我们可以在 Myfunc 和 Sum 函数中对 main 函数内的 i 切片进行操作。


但是,当我们对 num 切片进行扩容操作时,拷贝值的 value 指向的地址就可能会发生变化。


比如我们进行下面的操作:


func Sum(num ...int) {    num[0] = 8    total := 0    for _, i := range num {        total += i    }    num = append(num, total)    num[1] = total}
复制代码


运行结果是:


[2 7 3][8 7 3]
复制代码


这就侧面描述了 slice 的扩容算法。


另外说到可变参数,我们还需要注意几点,这里我们应该了解可变长参数应该是函数头中最后一个参数!!!


有些人会疑惑,不是说可变参数吗?怎么传入了一个切片?其实可变参数的底层就是用切片实现的,它是将传入的一个或多个参数转换为一个切片。

二、Go 中不允许不同类型的数据进行运算

我们都知道,Go 中具有极其严格的静态类型限制,只有相同类型的数据才能进行运算,那么如何解决这个问题呢?


第一点自然是强制类型转换。比如:


func main() {    var (        i int     = 3        j float32 = 3.1    )    fmt.Println(float32(i) + j)}
复制代码


这个程序运行就不会编译错误,运行结果是 6.1。


还有一种方法,不过适用场景比较单一。就是定义无类型常量。比如:


package main
import ( "fmt")
func main() { const i = 1 const j = 2.1
fmt.Println(i + j)}
复制代码


运行就不会报错,运行结果是 3.1.

三、不同长度数组能否进行比较

看一看下面这段代码:


package main
import ( "fmt")
func main() { a := [2]int{1, 2} b := [3]int{1, 2} if a == b { fmt.Println("equal") } else { fmt.Println("not equal") }}
复制代码


你觉得他们相不相等?


哈哈哈哈


其实都不能通过编译,因为数组的长度是数组的一部分,所以两个数组不是相同的类型,所以他们无法进行比较,故会报错:


invalid operation: a == b (mismatched types [2]int and [3]int)
复制代码

四、关于 map 的一点需要注意的地方

我们先来看看这段代码:


package main
import ( "fmt")
func main() { Map := make(map[string]int) delete(Map, "map") fmt.Println(Map["map"])}
复制代码


Map 是空的,你觉得会报错吗?如果不报错,会输出什么?


答案是不会报错,会输出 0.


是不是想对了?下面来解释一下:


Go 设计的就是删除 map 中不存在的键值对时不会报错,另外获取 map 中并不存在的键值对时,获取到的是值类型的零值。

发布于: 2021 年 12 月 08 日阅读数: 5
用户头像

还未添加个人签名 2018.11.07 加入

还未添加个人简介

评论

发布
暂无评论
Go语言学习查缺补漏ing Day5