当前位置:网站首页>Go-指针的那些事
Go-指针的那些事
2022-08-09 09:27:00 【草明】
<<Go 语言核心 36 讲>> 郝林 总结的
不可寻址的值:
- 常量的值。
- 基本类型值的字面量。
- 算术操作的结果值。
- 对各种字面量的索引表达式和切片表达式的结果值。不过有一个例外,对切片字面量的索引结果值却是可寻址的。
- 对字符串变量的索引表达式和切片表达式的结果值。
- 对字典变量的索引表达式的结果值。
- 函数字面量和方法字面量,以及对它们的调用表达式的结果值。
- 结构体字面量的字段值,也就是对结构体字面量的选择表达式的结果值。
- 类型转换表达式的结果值。
- 类型断言表达式的结果值。
- 接收表达式的结果值。
规律:
- 不可变的 - 寻址没有意义, 不能改
- 临时结果 - 例外, 切片字面量的索引结果值.
- 不安全的 - "不安全的"操作很可能会破坏程序的一致性,引发不可预知的错误,从而严重影响程序的功能和稳定性。
上代码, 自己品
package main
type Pet interface {
Name() string
Category() string
}
type Dog struct {
name string
}
func (self Dog) SetName(name string) {
self.name = name
}
func (self Dog) Name() string {
return self.name
}
func (self Dog) Category() string {
return "Dog"
}
func New(name string) Dog {
return Dog{
name}
}
func main() {
// 不会报错. 不需要指针类型调用 SetName
New("Max").SetName("Bear")
}
package main
type Pet interface {
Name() string
Category() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
self.name = name
}
func (self *Dog) Name() string {
return self.name
}
func (self *Dog) Category() string {
return "Dog"
}
func New(name string) Dog {
return Dog{
name}
}
func main() {
dog := New("Max")
dog.SetName("Bear") // 编译器会自动转换成 (&dog).SetName("Bear")
// 会报错, 因为 New("Max") 是临时结果, 不可以寻址, 无法获取指针
New("Max").SetName("Bear")
// cannot call pointer method on New("Max")
// cannot take the address of New("Max")
}
package main
import (
"fmt"
)
func main() {
map[string]int{
"the": 0, "word": 0, "counter": 0}["word"]++
map1 := map[string]int{
"the": 0, "word": 0, "counter": 0}
map1["word"]++
fmt.Println(map1["word"]) // 1
}
package main
import (
"fmt"
"unsafe"
)
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
self.name = name
}
func (self *Dog) Name() string {
return self.name
}
func (self *Dog) Category() string {
return "Dog"
}
func main() {
dog := Dog{
}
dog.SetName("Max")
dogP := &dog
dogPtr := uintptr(unsafe.Pointer(dogP))
namePtr := dogPtr + unsafe.Offsetof(dogP.name)
nameP := (*string)(unsafe.Pointer(namePtr))
fmt.Println(*nameP) // Max
namePtr = dogPtr + 64
unknownP := (*[]byte)(unsafe.Pointer(namePtr))
fmt.Println(*unknownP) // 内存泄漏, 获取到了某个地址指向的数据. 如果改了, 可能会导致不可知的问题
}
边栏推荐
- Ontology Development Diary 03-Understanding Code
- 本体开发日记02-sparql简单查询
- 约瑟夫问题的学习心得
- 1.线程简介
- [Environmental Construction] tensorrt
- 恶意软件查杀工具分享
- MySQL Checking and Filling Leaks (5) Unfamiliar Knowledge Points
- Summary of steps and methods for installing and uninstalling test cases that you must read
- GBase数据库中,源为 oracle 报出“ORA-01000:超出打开游标最大数”
- 关于链表的几道大厂面试题
猜你喜欢
随机推荐
try catch 对性能影响
8.递归遍历和删除案例
初窥门径代码起手,Go lang1.18入门精炼教程,由白丁入鸿儒,首次运行golang程序EP01
LPP代码及其注释
Redis high availability
约瑟夫问题的学习心得
Rights management model, ACL, RBAC and ABAC (steps)
Openwrt配置Aria2(Hg255d)
关于链表的几道大厂面试题
unix环境编程学习-多线程
你一定要看的安装及卸载测试用例的步骤及方法总结
Ontology Development Diary 05-Strive to Understand SWRL (Part 2)
oracle查看表空间占用情况并删除多余表所占空间
字符串
2.字节流
测试用例的原则、缺陷报告怎么写你都知道吗?
米斗APP逆向分析
These 12 GIS software are better than the other
常用命令之思科常用基础配置
真·鸡汤文