回到面向对象的传统编程规范上,一般实例化对象用的是关键字 new,而 new 并不是 Go 中的关键字.
Go 语言中的函数是一等公民,正如刚才说的 make 也不是关键字,同样是函数.
文章插图
即便对于同一个目标,Go 也是有着自己的独到见解!
new 不是以关键字形式出现而是以函数的身份登场,初步推测应该也具备实例化对象的能力吧?
文章插图
难道 new 函数不能实例化对象?为什么报错说赋值错误,难不成姿势不对?
吓得我赶紧看一下 new 的文档注释.
文章插图
根据注释说明,果然是使用姿势不对,并不像其他的面向对象语言那样可以重复赋值,Go 不支持这种形式,还是老老实实初始化声明吧!
文章插图
既然存在着两种方式来实例化对象,那么总要看一下有什么区别.
文章插图
文章插图
这里简单解释下 t.Logf("%[1]T %[1]v", myDynamicArray) 语句是什么意思?
%[1]T 其实是 %T 的变体,%[1]v 也是 %v 的变体,仔细观察的话就会发现占位符刚好都是同一个变量,这里也就是第一个参数,所以就用 [1] 替代了,再次体现了 Go 语言设计的简洁性.
下面再举一个简单的例子加深印象,看仔细了哦!
文章插图
%T 是打印变量的类型,应该是类型 type 的缩写,v 应该是值 value 的缩写.解释清楚了测试代码的含义,再回头看看测试结果,发现采用字面量方式得到的变量类型和 new 函数得到的变量类型明显不同!
具体表现为 _struct.MyDynamicArray {0xc0000560f0 10 10} 是结构体类型,而 *_struct.MyDynamicArray &{0xc000056190 10 10} 是结构体类型的指针类型.
这种差异也是可以预期的差异,也是符合语义的差异.
字面量实例化的对象是值对象,而 new 实例化对象开辟了内存,返回的是实例对象到引用,正如其他编程语言的 new 关键字一样,不是吗?
既然说到了值对象和引用对象,再说一遍老生常谈的问题,函数或者说方法传递时应该传递哪一种类型?
值传递还是引用传递接下来的示例和动态数组并没有什么关系,简单起见,新开一个结构体叫做 Employee,顺便回顾一下目前学到的封装知识.
文章插图
首先测试引用传递,这也是结构体常用的传递方式,行为表现上和其他的主流编程语言表现一致,方法内的修改会影响调用者的参数.
文章插图
文章插图
unsafe.Pointer(&e.Name) 是查看变量的内存地址,可以看出来调用前后的地址是同一个.
文章插图
文章插图
调用者发送的内存地址和接收者接收的内存地址不一样,符合期望,值传递都是拷贝变量进行传递的嘛!值类型还是引用类型的区分无需赘述,接下来请关注一个神奇的事情,方法的接收者是值类型,方法的调用者是不是一定要传递值类型呢?
文章插图
方法的调用者分别传递值类型和引用类型,两者均能正常工作,是不是很神奇,好像和方法的定义没什么关系一样!
文章插图
文章插图
虽然方法的接收者要求的是值类型,调用者传递的是值类型还是引用类型均可!
文章插图
仅仅更改了方法接收者的类型,调用者不用做任何更改,依然可以正常运行!
推荐阅读
- 茶人必知六宗最
- 什么是Spring?
- TCP粘拆包详解与Netty代码示例
- 从零完成k3s Kubeconfig配置
- 梦到下山是什么意思啊 梦到下山路很陡很危险很难走
- 回溯 什么是Python回溯? Traceback
- 别人梦见我生小孩是什么征兆 别人梦见我生小孩
- 主板上到处都可以看到电容,每颗电容在每个电路作用是不一样的
- 亨利福特发展的制造技术是什么 亨利福特对汽车工业的贡献
- 什么是系统架构?