美文网首页
Golang:关于寻址的一些问题

Golang:关于寻址的一些问题

作者: Rollover | 来源:发表于2020-03-03 21:07 被阅读0次

Go 语言有点像 C 语言,它有指针,用 * 标识一个指针,用 & 标识一个地址,但 Go 语言的指针比较简单,没有指针运算。

字面量不可寻址

先来看一段程序代码:

package main

import "fmt"

type Programmer struct {}

func (p *Programmer) FindBug() {
    fmt.Println("Yes, you are")
}

func Create() Programmer {
    return Programmer{}
}

func main() {
    Create().FindBug()
}

在 Go 语言中,字面量是不可以取值的,上面的结构体 Programmer 有个指针接收者的方法 FindBug ,但是,我们在函数 Create 中返回的是一个字面量的 Programmer{} 结构体,它没有地址
,所以这段代码运行会报错。
解决方式:
1.修改为可寻址:

// 1. 让 Create 函数 返回一个地址
func Create() *Programmer {
    return &Programmer{}
}

// 2. 不改变 Create ,用变量接收 Create 的返回值
func main() {
    var c = Create()
    c.FindBug()
}

2.把指针接收者改为值接收者

func (p Programmer) FindBug() {
    fmt.Println("Yes, you are")
}

切片和数组寻址的问题

还是先来看一段代码:

package main

import "fmt"

// 返回一个长度为3的数组
func newArray() [3]int {
    return [3]int{1, 2, 3}
}

// 返回一个长度为3的slice
func newSlice() []int {
    return []int{1, 2, 3}
}

func main() {
    arr1 := newArray()[1:]
    fmt.Println("arr1: ", arr1)
    arr2 := newSlice()[1:]
    fmt.Println("arr2", arr2)
}

如果你使用 IDE 的话,会提示如下错误



很明显,字面量的数组不可寻址,上面的 newArray 调用可简化为:

arr1 := [3]int{1, 2, 3}[1:] // 字面量数组寻址是不合法的

但是,我们先将数组赋值给变量 arr1 它就有地址了,于是我们将代码改为如下:

arr1 := [3]int{1, 2, 3}
arr1 = arr1[1:]

这段代码也会报错,大家可以先思考下为什么会报错?</br>
报错的原因就是,数组在做切片操作的时候会变为一个 slice ,而变量 arr1 的初始类型为数组,arr1[1:] 则是一个 slice ,所以再次对 arr1 赋值的时候类型不匹配所以报错。

PS:大家再看一些代码的时候,如 变量 := 数组[:] 就是把一个数组转换成一个 slice

那么,slice 字面量为什么能做切片操作(可寻址)呢?实际上 slice 内部的结构是一个结构体,也是对底层数组的一个 view。
每一个切片间接引用一个元素序列。尽管一个非空切片是不可取地址的,它的内部元素序列需要开辟在内存中的某处因而必须是可取地址的。 取一个切片的元素地址事实上是取内部元素序列上的元素地址。

这就是为什么不可寻址的非空切片的元素是也可以被取地址的。

相关文章

  • Golang:关于寻址的一些问题

    Go 语言有点像 C 语言,它有指针,用 * 标识一个指针,用 & 标识一个地址,但 Go 语言的指针比较简单,没...

  • GO语言面试系列:(三)关于golang闭包所谓的“坑”

    关于golang闭包所谓的“坑”,昨天听了某企业架构师关于golang的经验分享,听到架构师吐槽golang里的闭...

  • go mod特定依赖包处理

    自从golang原生支持go mod以后,将golang应用依赖处理统一和标准化了,但是在使用中还是会遇到一些问题...

  • 可寻址,不可寻址

    //可寻址,不可寻址map中的元素不可寻址,切片中的元素可寻址 使用指针作为方法的 receiver只要值是可寻址...

  • 【Golang】可寻址性-map和slice的区别

    map 使用值作为map的value 使用指针作为map的value(这里也可以当做为解决上述问题的办法) 小结:...

  • ARM笔记

    一、寻址方式 立即数寻址 如:MOV R0, #6;表示:R0 <- 6; 寄存器寻址(直接寻址) 如:ADD R...

  • vscode安装go插件

    学习golang时,在给vscode配置插件时遇到一些问题,像godef,gopkg,dlv能自动安装成功,但是其...

  • golang error 处理

    用了golang也有一段时间了,在我推动golang在公司项目应用工程中也发现了很多问题,关于公司的golang工...

  • 8. 汇编-ESP寻址 EBP寻址

    8. 汇编-ESP寻址 EBP寻址 寄存器传参和堆栈传参 寄存器传参 堆栈传参 --ESP寻址 堆栈传参 --EBP寻址

  • ARM汇编之内存寻址模式

    对加载和存储的汇编指令目前有三种寻址模式:偏移寻址(Offset addressing),前变址寻址(Pre-in...

网友评论

      本文标题:Golang:关于寻址的一些问题

      本文链接:https://www.haomeiwen.com/subject/zisllhtx.html