自学go中(一)

自学go中(一)

内容偏向于实践,不会过度的说明语法内容。更多的专注于自己对go的一些认识和使用中让我感觉疑惑的内容。

指针,方法与接口

在go中你会看到各种地方都在使用指针,不管是receiver,参数(方法输入参数或者返回参数),了解指针的使用方法是非常重要的,不然会遇到各种问题。

指针的作用就不多说了(因为我是使用Java的,以前很少去关注指针的内存。在Java中如果使用的是对象,那么这个对象调用方法或者把这个对象作为参数出入到一个函数中,都是使用的这个对象的引用,其实就是这个对象的地址。)但是在go语言中就要重点区分指针和值类型了。

方法

方法在go中非常特殊(如果和Java或者C++这类语言去比较的话),在Java或者C++中,方法是属于某个类或者对象的(static方法是属于类的,其他的方法是属于对象自己的,所有当一个对象在调用自己的方法的时候,方法内对本身对象的内容作了修改是可以直接反正到这个对象身上的。所以Java对象或者C++对象在调用方法的时候是隐藏了this指针)。但是go中没有对象,只有结构体这个概念。如果严格的按照C语言的传统,go是没有面向对象的功能的。为了实现面向对象的功能,go中需要施加目标,显示的传递(不一定非要是指针,也可以是值类型)。

从上边内容就引出了方法的receiver,也就是方法有一个接受者。其实这个接受者类似于Java的调用这个方法的内容(java中的内容是对象,但是go中可以是引用——指针,也可以是值),如下所示:分别实现了两个方法fun1与fun2

type test struct {
    a int32
    b int32
}

func (t test) fun1() {
    println(&t)
}
func (t *test) fun2() {
    println(t)
}

但是方法的接受者不同,一个是值类型,一个是引用(指针)类型。在go中,值类型可以调用指针方法,指针也可以调用值类型方法,如下所示:

func main() {
    var t test
    t = test{1,2}
    println(&t)
    t.fun1()
    t.fun2()
}

输出的结果为:

0x421111f70
0x421111f68
0x421111f70

可以看到结果,值类型调用接受者为值的方法的时候,传入方法内容的是这个值的拷贝,但是在调用指针类型的方法的时候,确实这个值对应的指针(毋庸置疑,fun2是可以对t中的值进行修改的,fun1是无法对值进行修改的)。

同样在go中,指针类型可以调用值方法,也可以调用指针方法,如下所示:

func main() {
    var t *test
    t = &test{1,2}
    println(t)
    t.fun1()
    t.fun2()
}

输出结果为:

0x421111f70
0x421111f68
0x421111f70

从结果可以看出来,虽然值接受者被指针类型调用了,但是最终的结果可以看出来,效果和接受者有关。

目前的总结:不管真是调用方法的接受者是指针类型还是值类型,最终真是调用方法的类型与方法的声明相关。也就是指针类型的声明的方法,调用者如果是值类型会被转化为指针类型;如果是值类型声明的方法,调用这如果是指针类型会被转化为值类型。

接口与实现

接口的概念很简单,在go中接口的功能和其他语言中接口的功能是类似的。都是定义了一组功能的操作而已。
但是go中对接口的实现是不同,首先go中没有对象,类的概念,所有实现接口只能让struct结构体来做。所以一个结构体实现接口其实就是为这个结构体添加对应的接口的全部方法。但是我们知道,一个结构体的方法有两种类型(按照receiver是T或者是*T进行区分),当一个结构体在实现接口的时候,接口中的一个方法只能被这个结构体的值(T)类型实现或者被(*T)类型实现。
所以对于一个接口而言,要么是某个结构体的值实现了这个接口,要么是某个结构体的指针实现了这个接口

虽然一个接口中方法,某些可以让结构体的值实现,某些可以让结构体的指针实现,但是这种方式是不推荐的。

当在把接口作为函数的参数或者返回值的时候,在具体传入参数或者返回参数实现的时候,是需要考虑你返回的具体实现的结构体应该是指针类型的还是值类型的。(返回的类型依据实现接口的类型决定)。如果是按照指针类型实现的接口,那么都应该使用指针;如果是按照值类型实现的接口,那么可以传输值或者指针类型;如果既有值类型实现的方法,又有指针类型实现的方法,那么传输的时候应该传输指针类型的。

具体在调用接口的方法的时候的效果,与上小结方法的说明相同,也就是说如果实现这个方法的接受者是值,哪怕是指针调用,也只能实现值的效果

如下所示:一个接口say,实现的结构体hello

type say interface {
    s1()
    s2()
}

type hello struct {
    a int32
    b int32
    c string
}

func (h *hello) s1() {
    h.a = 100
}

func (h hello) s2() {
    println(&h)
    h.b = 200
}

func method(say say) {
    println(say)
    say.s2()
}

func main() {
    hello := hello{}
    println(hello.b)
    method(&hello)
    println(hello.b)
}

可以看到传入method的参数是hello的指针,并非结构体的值。如果把s1的方法的接受者改为值,那么method中传入的参数既可以是指针类型,也可以是值类型的。

重点提示:在没有特殊情况下,实现接口都直接使用指针的方法。

重点概念

  1. 语言关系:go和C语言之间是有语言关系的,但是和C++之间是一点关系都没有的。C语言中有结构体,go语言中也只有结构体。(但是C++中就是对象了)

问题

  1. 官方文档,go中可以值类型调用指针方法吗,或者指针方法调用值类型
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容