美文网首页
可寻址,不可寻址

可寻址,不可寻址

作者: anthonydan | 来源:发表于2020-03-17 17:20 被阅读0次

//可寻址,不可寻址
map中的元素不可寻址,切片中的元素可寻址

使用指针作为方法的 receiver
只要值是可寻址的,就可以在值上直接调用指针方法。即是对一个方法,它的 receiver 是指针就足矣。

但不是所有值都是可寻址的,比如 map 类型的元素、通过 interface 引用的变量:

type data struct {
name string
}

type printer interface {
print()
}

func (p *data) print() {
fmt.Println("name: ", p.name)
}

func main() {
d1 := data{"one"}
d1.print() // d1 变量可寻址,可直接调用指针 receiver 的方法

var in printer = data{"two"}
in.print()  // 类型不匹配

m := map[string]data{
    "x": data{"three"},
}
m["x"].print()  // m["x"] 是不可寻址的    // 变动频繁

}
cannot use data literal (type data) as type printer in assignment:

data does not implement printer (print method has pointer receiver)

cannot call pointer method on m[“x”]
cannot take the address of m[“x”]

. 更新 map 字段的值
如果 map 一个字段的值是 struct 类型,则无法直接更新该 struct 的单个字段:

// 无法直接更新 struct 的字段值
type data struct {
name string
}

func main() {
m := map[string]data{
"x": {"Tom"},
}
m["x"].name = "Jerry"
}
cannot assign to struct field m[“x”].name in map

因为 map 中的元素是不可寻址的。需区分开的是,slice 的元素可寻址:

type data struct {
name string
}

func main() {
s := []data{{"Tom"}}
s[0].name = "Jerry"
fmt.Println(s) // [{Jerry}]
}
注意:不久前 gccgo 编译器可更新 map struct 元素的字段值,不过很快便修复了,官方认为是 Go1.3 的潜在特性,无需及时实现,依旧在 todo list 中。

更新 map 中 struct 元素的字段值,有 2 个方法:

使用局部变量
// 提取整个 struct 到局部变量中,修改字段值后再整个赋值
type data struct {
name string
}

func main() {
m := map[string]data{
"x": {"Tom"},
}
r := m["x"]
r.name = "Jerry"
m["x"] = r
fmt.Println(m) // map[x:{Jerry}]
}
使用指向元素的 map 指针
func main() {
m := map[string]*data{
"x": {"Tom"},
}

m["x"].name = "Jerry"   // 直接修改 m["x"] 中的字段
fmt.Println(m["x"]) // &{Jerry}

}
但是要注意下边这种误用:

func main() {
m := map[string]*data{
"x": {"Tom"},
}
m["z"].name = "what???"
fmt.Println(m["x"])
}
panic: runtime error: invalid memory address or nil pointer dereference

相关文章

  • 可寻址,不可寻址

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

  • ARM笔记

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

  • 学习Unity新出资源管理系统-Addressable Asse

    1.什么是Addressable(可寻址资产)系统 可寻址资产系统提供了一种通过“地址”加载资产的简便方法。它通过...

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

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

  • Go语言的指针

    哪些类型不可寻址 1, 不可变的值不可寻址。常量、基本类型的值字面量、字符串变量的值、函数以及方法的字面量都是如此...

  • Unity Addressable Asset System 文

    简介 Unity可寻址资源系统 可寻址资源系统提供了一种简单的方法通过“地址”加载资源。简化资源包的创建和部署的管...

  • ARM汇编之内存寻址模式

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

  • 8086 指令系统寻址方式

    整理汇编语言学习笔记,回顾一下8086 指令系统的寻址方式。 寻址与指令 寻址方式(Addressing Mode...

  • 汇编语言中@,#是什么含义

    "#"表示立即数寻址。采用立即寻址方式的指令,在立即数前面加上立即寻址符“#”。例如指令MOV A,#30H中30...

  • Git还是从底层命令开始吧

    Git 是一套内容寻址文件系统,那么Git是怎么进行寻址呢?其实,寻址无非就是查找,而Git采用HashTable...

网友评论

      本文标题:可寻址,不可寻址

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