00:00
我们继续来看一下继承的深入讨论的另外一个部分,我们看第四一个啊,同学们看,那如果说结构体里面嵌入了两个或者多个匿名结构体,这是有可能的,对不对,你比如说大家看这里。看这里,你比如说你这里有个A结构体,这儿有个B结构体,那么A和B呢,都被嵌入到了C这个结构体里边,这是有可能的,而且更可悲的是什么呢?就是A,它有内容字段有。还有这个H字段,而B里面也有一个name字段。那这样的话怎么办呢?就说如果两个匿名结构体都有相同的字段或者方法。同时啊,同时结构体本身没有同名的字段和方法。就说你两个匿名结构体有name,但是呢,我这个C里面没有这个name。再说一遍啊,就是说A和B里面有内容,但是C没有这个同名的这个字段或者方法,在这种情况下。
01:00
在这种情况下,在访问时就必须明确指定匿名结构体的名字,否则编译直接报错。什么意思,就说。就是说如果你签了两个结构体,这两个结构体有相同的字段和名字。但是你这个。这个C却没有。却没有这种同名的这种字段和名字,那么这个时候你为了区分到底用A的还是用B的,就必须把这个匿名结构体的名字带上,否则编译就会出错。那我给大家举个例子。大家看案例。这这一点也是我们在使用的时候是需要同学们注意的一个细节,那我给大家举个案例,大家看一下啊,同样我还是在这儿举例吧。那干脆我们先写一个,先写一个文件夹,不然的话这个文件就越来越多了,在这就比较混乱。那我还是写这个东西叫做什么呢?叫做继承啊,继承的details。
02:02
二同样在这里面呢,我们新建一个文件叫main.go没有问题吧?好,打一个包包,Package主包,然后import。然后有个对不对,然后写一个主函数,每。那这个时候呢,我们来写。我们来写你这个这个类型啊type。Type,那么首先我写个A。这个A这个结构体里边structure。A,结构体里面呢,它有这么两个字段,一个是name。十寸。再来,再有一个age int,好吧。然后呢,还有一个,还有一个结结构体type b,它也是个结构体里面呢,它也有一个name。它也有一个name是寸,注意听啊,然后呢,它还有一个别的字段,比如说score sc它有一个什么呢?成绩FLOAT64。
03:03
好,这个就写完了,呃,那这个时候呢,我们又有一个结构体叫C。它也是个结构体,它呢嵌入了A和B。它嵌入A和B,好,现在我们来看看此时此刻啊,比如我定义了一个C这个结构体。那这个时候我要给他赋值,我这样写就会报错了。比如说我给大家一个to,大家想这个地方就L,为什么这地方会错误呢?因为大家想啊,因为你在这个地方去访问这个name的时候。根据原先我们说的访问规则和它的顺序,他是不是先到C里面去找啊,C有没有这个name,没有,那没有的时候他就会到嵌入结构里面,A和B里面去找,那么他发现A有一个,B也有一个,完了。他不知道到底你把这个name给A这里面的name字段呢,还是给B这个结构体的字段呢,于是它就会编译报错来,我保存一下。
04:02
到不一保存这边就会到一个错误,大家看这里编译已然出错了啊,在这大家看到他说这这个地方它是一个模糊的,他不知道你这个选择器到底选哪一个。这。这个地方就是呃,模模糊不明确的意思,不明确的一个选择题C点内,那这个时候你怎么办呢?你只能加上这个A点哦,这样就明确了,说我就告诉你我要找A里面内,这就没问题了。对不对,好,这个地方大家注意一下,当然了,我再问大家一个问题,假设我这个name里面就有一个时寸就有一个name,好它也不会报错,因为如果你这C里面本身就有一个name,那这个时候他很清晰啊,他说我先到C里面去找O已然找到了,那找到这个的话,A和B它就不会再去找了,也就不会再发生一个选择器不确定的问题,各位。大家看我保存一下,当我一保存你看代码是吧,就没有错,只是这报了一个错,报的是什么错呢?就说你没有用用这个format好,我把这个地方给它整理一下。
05:06
PT。好,我把这个输输出我说一下啊,注意听。注意听啊,嗯,当如果如果C。没有name。没有name字段。内蒙字段。而字段啊字段。而什么呢?而这个A和BA和BA。有。有这个内幕字段,那这时。啊,这时就必须就必须通过指定。指定什么呢?都必须通过指定这个匿名结构体名来来区分匿名结构体名字来区分。能理解这意思吧,就是你必须得通过名字那看啊,我把这个注销。你这地方如果不写就报错了。看到没有就报错了,那这个时候你只能这样写才可以。
06:02
啊,那这个时候呢,你这样写就不对,对吧,所以。所以。所以什么呢?就是C点内肯定是行不通的。就错的。就会就会报报什么呢,编译。错。好,这点大家注意一下啊,大家错一下,好,那这样子我们写就没有错了,这点大家注意一下,就是在使用的时候一定要注意这个细节啊,要注意这个细节,否则你是不行,当然还有方法也是一样的道理,我就没有举例了。方法也是一样的啊,同学们。你方法假设A有一个方法叫c hello b有一个方法也叫C哈,好,那你这直接调动是c.C哈,那也是区分不了的,除非你C本身有个c hello。啊,像我在家一样啊,对于。这个这种情况啊,这个这个规则,这个规则对什么呢?对这个方法也是一样的,也是一样的。OK,注意这个这个细节,好,那我把这段代码呢,给大家整理一下啊,整理一下就放到这边来吧,好吧。
07:04
这个细节大家注意一下,保存一下。好整理啊整理,把这个代码稍微的往上走一走,代码看起来比较清晰一点。好,我现在从这开始截,截一段代码过来。没有问题吧?好,把它放好。然后呢,我把它搁在这就行了。好,这是我们讲的第四一个需要注意的地方,我们看第五个需要注意的地方是什么?如果一个结构体嵌到了一个有名结构体这种模式呢,我们把它叫做组合,这个我们一般不把它称之为继承的,它是组合式继承的一种特殊关系,如果是组合关系,那么在访问组合的结构体字段时,字段或者方法时,这写错了啊,叫方法。方法时,就必须带上结构体的名词,那大家看,这个就叫组合,你甚至可以多组合多个这个A。你看这个在假在这个功浪里边,它这个呃,继承是非常灵活的,看到没有,你看啊,假设我这有个A里面有name,有age,那这个地方我嵌套了一个A,同时呢,我指定的名字,那这个时候同学们注意听,你这个时候要要访问这个name啊,就必须你这个A,你要访问到A里面的啊,你要你要访问到A里面的name,就必须把这个名字带上,否则它也是把访问不成功的,明白这意思吧。
08:26
啊,那么我把这个呢,也给大家整理到这里。这也是个细节。第五个细节。对吧,好,我给大家简单的举个例子证明一下这个事儿。我们走一下,走一下代码,我就在这直接走一下啊同学们,那现在呢,我写一个type。Type dru。我简写一个名字。好,然后呢,在这个里面呢,我们嵌套了一个A。但是这个呢,就叫。有名,这个就相当于说在嵌套这个结构体的时候,给这个结构体有个名字,因此呢,我们就说嵌套了一个有名结构体。
09:04
如果是有名结构体的话,要使用就得这样去使用,大家看啊,比如说我VRDD看到啊,我定义定我在这生命的一个D这种结构体变量,对吧,那么现在我们A点内以前这样写是不是是可以的呀。是不是以前我这样写?d.name它是可以的,那这个时候我们来看看行不行。给他一个J保存一下。好,我们看到这时他就报错了,他说a.on defend,他为什么呢?他说type d还是no fair or method,他说在这个D里面没有这个方法,因为你这个地方不是一个逆名结构体,那么在这个检查的规则的时候,他就干什么呢?注意听他就。他就会编译器只在这个B里面看有没有内幕,如果没有就直接报错了。啊,也就是说,也就是说,因为你这个地方不是匿名结构体,它就不会往上找。明白吧,他就直接你,他就直接在这个D里面看有没有这个name,如果没有,他就直接告诉你D没有这个字段或方法。
10:07
所以你看在这个勾浪里面,它这个层级关系它是很清晰的啊,如果当然如果说老师我把这个去掉,去掉那肯定就对了,去掉肯定不报错,但是你写上就要报错。明白吧?好,那怎么办呢?就按照老师说的A点这个就可以了,你就必须把名字带上了。必须把名字带上了,看这样就可以了。啊,这样就可以访问到啊,当然有同学又说了,说老师。假设你这个name,这个D里面也有一个name呢?大家想一想,如果我有一个name。我这样写会不会报错?肯定大家想这样写他是不会报错的,因为他还是先到地面发现他有吗?有那就没问题了。对不对,但是如果你没有好,你没有的话。那就没没什么可说的了,那他就会他就会,他就发现你这个是有名结构体,他也不会到A里面去看有没有类,直接报错,明白吧,好这个地方我把它写到写出来OK。
11:05
好,这个细节大家注意一下啊,好,我把这个核心的地方给它写进去。这样子啊,下一句话。这句话。就是。呃,如果地地的地中是一个有名。有明结构体。结构体则则怎么样呢?则这个有名结构体的话,那么再访问。在访问。呃,有名结构体时必须带上这个名字,则访问。有名。有名结构体的字段史。只能是,就必须带上。带上这个,呃,名字就是有名结构体,这个名字啊,就就带上。有名结构体的名字。比如。比如这里的比如什么呢?D。
12:03
地点。d.a点内啊,这样子一回事,大家看是不是这个道理啊,要把这个A带上,好,我把这个呢给同学们整理一下,同时这个关系,别人问到你这个叫什么关系啊,这个就叫组合关系。啊,这个就叫组合,就说D和A组合起来了,明白这意思吧,这叫组合关系。好的,我把这段呢给同学们放到这里来。大家跟上思路哈。封好,同时呢,我把它使用的时候这一段代码也给大家拿过来。是吧,是不是这样用的呀,核心代码。这用的。要把哪个加上呢?同学们要把这个加上啊,这样修你就不能直接写D,就不能这样写这个D点这个内容就不能这样用了啊,必须把这个A带上啊,同学们好,我把这个呢给它放到这。好,这个OK了,紧接着呢,我们来看第第六一个需要同学们注意的地方,第六一个,那第六一个呢,嗯,它是这样子的,就说嵌套匿名结构体后,也可以在创建结构体变量实例时,直接指定各个匿名结构体的字段值。
13:17
什么意思呢?我我直接给他举例子。啊,这种用法也很也也会很多,大家看我们在前面,我们在前面写了一个细节的时候,大家还记不记得,我们是这样给给名字的看。我们这样给值的,比如说我建一个pupil pupil建完了过后,我再给他name和age赋值,这个很麻烦。这个很麻烦很麻烦,因此呢,这在勾浪里面呢,它也可以直接在创建这个结构体变量时,它直接给各个匿名结构体的字段赋值也是可以的,那我给大家演示一个案例,我还是在这演啊,还在这演好吧。那现在呢,有这么一个情况,比如说我有我有一个类型叫type,我就直接这样写。
14:03
Type。Type好type呢,我有一个呃这样信息吧,比如说有个D,我就写个嗯。学生和我想啊。我写一个这样的关系,比如说animal,啊,固执吧,固执,好吧,固执它是一个结构体。这个故事里面呢,有name。Your name好固执呢,也有一个价格,Price,好,FLOAT64没问题吧,好。这有一个结构体,这一个结体,那么同时呢,我还有一个结构体啊,还有一个什么结构体呢,我们认为除了商品之外呢,我们还有一个叫做品牌对吧,品牌brand brand brand。好注意听啊,那么这个时候呢,品牌呢,我们认为也有一个这个名字,还有一个什么信息呢,比如说品牌呢,呃,它有一个地址,他是在哪注册的,好吧,嗯,ADD。
15:01
ADS好地址。写完了,那这个时候呢,我有一个结构体叫叫做什么呢?叫做book,叫做这个,我想想啊,叫做这个,嗯,电视机TV好吧,TV。那么这个呢?Struggle的呢?他把这个固执。还有还有他把这个故执,还有这一个brand同时呢给放进来了,比如说我我把我在这边同时嵌入了固执和brand,也就是说我这个TV电视呢,既是一种商品,同时呢,我也用到了人家的一个品牌。对不对,这是可以的,那我现在创建一个TV,我可以这样创建呢,名字,价格,还有它品牌的这个名字,以及他的地址在哪个地方,我们都可以一次性的给它创建起来,大家看怎么创建。啊。我把这个细节给大展过来啊。好,同学们,看我怎么用它。我们原先是先创建一个TV,再一点点复制,这个太慢了,太麻烦了,我就直接起TV。
16:06
走好,大家看我怎么做啊,我就直接这样做了。看到那这里面呢,我就直接写第一个,第一个是固执。第一个你是不是固执啊,我就把固执给他,这个故执里面呢,它有两个字段,一个是商品名,比如说是叫做什么呢,叫做电视机。电视机对电视机电。电视机啊,诶这么电视机。好,电视机什么呢?001哦,这是它的一个商品的名字,价格呢,我也可以可以把它写进来,比如说是5000块钱,五千九十九,写完了同时我再打一个逗号。打个逗号呢,我说诶,那既然这样的话,我把品牌一样,因为你这不是还一个品牌吗,我把这个品牌也粘过来。同样我也可以给品牌来来名次,比如说品牌是海尔的。
17:04
对吧,海尔。那海尔呢,同样呢,他有个地址叫,比如在山东青岛。山东啊山。山东是吧,山东好,这写完了,你看这样子,当然这个后面的就要给个逗号啊,注意这方要给个逗号,这样我们就把TV建立起来了,就说我再去创建这个,呃,这个有嵌套结构体的这个变量时,我就直接把这个给他了,那么我们来执行一下,看看可不可以跑起来print。TV走TV好,我们运行一下看效果啊。我们来跑一跑。我们发现,诶这地方没有对。CD到。涉及到细节二是吧。Detail。细节二。好,我们go run。我们写的这个代码。
18:00
面点购我们看一下代码,同学们看到,诶,你看到电视机有了,海尔也有了,是吧,可以重建,甚至你也可以,这是一种形式啊,你也可以这样写,涂老师我能不能这样写呢?也可以,比如T2有些人喜欢这样写,他说老师我直接把字段名给他也可以,他是这样的。啊,就换行,这样看起来更清晰。好,怎么写呢?也可以这样,就是这个地方他接着换行。二换行看啊怎么写?首先这个地方我指定名字对吧,诶然后呢。换一行这边是这个估值里面不是还有价格吗。把价格也给大家单独的放到这来。也可以这样用,这样不要忘了有一个逗号,这样有什么好处呢?这样的好处就是我不依赖于你固执这个顺序了,甚至我可以把price写到上面去都可以。你刚才这种写法就必须按照这个顺序写,否则肯定是要报错的,就说你在定义这个故执的时候,你的名字写在第一位,那你就这必须写固执,然后第二个才能写价格,但是如果我这样写的话,我可以把价格写在前面,把名字写在后面,因为我不依赖你,不依赖于你的顺序,明白吧,当然这个呢也是一样,可以这样去修改。
19:20
好,我给大家都改编了啊。好,同样这旁它有一个名字对吧,叫海尔,同样它有个地址ADS山东,同样最后有一个对话。好,这样子也可以,那么我把这个改一改啊改成。二然后这个呢是夏普。啊,夏普这个品牌,然后地址呢,假设是北京,我就随便写一个啊北京我也不知道在哪的北京写完了,那这个时候我们再来输出。form.print好TV2,然后呢,有一个叫TV2输出来。我们跑一下跑起来,我们可以看到这个也是OK的。
20:03
看到没有,这两种形式大家都可以任选,而且呢,还有一种形式啊,同学们,我再多说一句,有些人喜欢这样去这样去进行一个呃嵌套,比如说我有第二种电视,那么他直接用的星号,这样也是可以的。这样也可以,就是说我们再去嵌套一个匿名结构体的时候,其实也可以嵌套这个匿名结构体的什么呀,指针类型。这样呢,它签到直接就是指针,返回来就是地址,效率更高,那我们给他演示一下这个又怎么用来吧。那一样啊,我为了省点事,我就把这个粘贴复制一份,好吧,粘贴复制一份,但是呢,有些地方要变化。啊有变化,所以第一个这肯定要改成地址了。明明白意思吧。假如TV3。我先把这个改完了,再改第二个啊,T3里面这个地方。哎,对,我想想啊TV啊,这个还是不用变化,这个还是TV这个没变化,只是里面呢变成地址了。
21:03
明白啊,里面变成地址了,这是可以的。当然我在这边呢,把这个改成电视机三好吧,价格改成7000。呃,改成一个品牌叫什么呢?还有什么呀,叫做这个创维。创维。创。好电视,呃,在哪里呢?比如叫在这个成都。那在哪里啊,比如教授在河南。和。对吧,我写到这这这也可以,那么这个时候呢,我们也把它输出来一下,大家看这个时候输出的内容是什么东西啊,大家看一下TV3TV3。我们看看TVB3这个时候行不行,跑起来。我们发现这方有问题,大家看在哪个地方出了错了呀。在这出了错了,这样子他有问题啊,他不让他们去使用,如果他不让这么去使用,原因是为什么呢?我们来猜测一下是哪里出错了,大家想一想,这该给的是不是也也都给了,给的是地址吗?你要的指针我返回指针,但是为什么会错呢?大家想一想,动脑筋想一想。
22:10
看出来哪里错了没有,是不是这应该是二啊,因为我这定的是不是二啊,你别把它搞错了是吧,所以你这方是没有写对的啊,因为是TV2里面这个是没有错的啊,没有错好我们跑一个现在现现在应该是没没毛病的,大家看这里,但是我们会发现很奇怪的现象,他是不是返回两个地址啊。为什么返回地址?为什么?因为你本身就是把地址给了人家嘛,人家返回地址也是顺理成章的事,那怎么把它取出来呢?取出来也很简单,要这么去取啊,同学们,你要取的话呢,得这么取。首先呢,你。要。把它取出来的话,这样子点。对不对,因为你在用的时候,你是针对这个指针用的,所以说把它先拿过来。对吧,你要先把它拿过来,然后再使用。
23:02
那这个时候你要用的时候,其实前面应该有一个取值符,对不对,就是把那个取取值符把它取出来,然后呢,咱们再把这个固值打出来,你里面有个估值嘛,啊这样就对了。那同样我们要取出它的brand,也要这么去操作,明白意思吧,诶,这样才行。好,我们把brand取出来。好,我们来运行一下同学们。好,这时呢,我们看到值就对,正确了是吧,把电视机和创维荷兰取出来了,同样道理啊,同样道理,如果你这地方要分开写也是可以的。比如说我TV4。TV4的话呢,我想把它分开写,也也可以,比如说我这换一行。对吧,我这换一下啊,这个地方就稍微代码多一点了。好,我把它换好。好的,那这个时候这个地方也可以再换。这边也可以再换对吧。
24:01
诶好,这样子就就是一对,然后这边换下来,我们把名字给他,比如说那。对吧,那然后这个地方是电视机是。呃,然后呢,这个价格比如是9000品牌,我们是长虹。傲娇是长虹。那长虹呢,在哪里呢?比如在四川。对吧,四川OK,这样也可以用啊,这样就说直接把名字写上也可以。把字段的名字和值给它对应上也可以,这是地址ad res。好,这个呢,我们少了一个什么呀,价格price对吧?好这个时候我们再输出一下TV4。TV4。四。是好,我们来跑一下,看看现在用起来行不行,哎,这少了一个什么呀,少了一个逗号。把这个逗号加进去。跑一下。我们看代码,看长虹四川好同学们,关于这个就是我们。
25:05
我们这是在一个结构体里面嵌入了多个多个匿名结构体时,我们在创意的时候呢,也可以这样直接去复制,不然的话你别人这么去写,你一下就蒙圈了,你看不懂知道吧,看不懂好,那关于这个代码呢,我们就把它整理一下,整理到笔记里面去。因为这个代码呢,相对比较多啊,相对比较多,老师呢,就偷一个栏,把这个代码直接怎么样拷贝过来就完了,好吧,诶还不行这个代码。还有点多哈,有点多,那这样子,我我我把那些核心代码拿过来吧。这一段是核心代码。是吧,这段是我们来定义的啊,定义的时候大家看到在这里呢,我们嵌入了good brand。还有固执不让的指针。好,先把它放一下。这一块先做好,紧接着呢,我们在使用的时候,我们是怎么使用的,大家看一下我们在使用的时候呢。
26:03
在这我们有几种用法,当嵌套匿名结构体后,也可以在创建结构体时直接指定各个匿名结构体字段的值。怎么用的呢?有这么几种用法对吧?我把它整理一下。走一个这个是58。到82。58~82,好把它整理一下。58~82 OK整理啊。好,紧接着呢,我们再往下面看。啊,这个地方已已经到82行了,对吧,82行接着往下截取。82,那就是83了。OK。好把这个呢给它整理到这里,到位了。好,把它尽量放在同一同一行吧,好,同学们看看这个地方应该不难吧?好,那么我们来回顾一下我们讲了哪些细节啊,这里面我们又讲了三个需要同学们注意的地方,第一个就说当一个结构体创建呃,嵌入了多个匿名结构结构体的时候,那这个时候如果如果两个匿名结构体有相同的字段和方法,同时结构体本身没有这个相同字段和方法怎么办?你得明确指定结构体的名字,否则编译错误,在这里写的出来。
27:26
必须要把这个A带上,第二个如果一个结构体签到了一个有名结构体,那么这种模式我们首先要知道它叫组合了啊组合,那么组合其实也是继承的一种一种体现,对不对,这点大家要清楚,但是这个时候呢,跟原先不一样,就说必须要把这个名字带上,要把这个有名结构体的名称带上,否则它是要报错的。第六一个就是如果我们去创建一个嵌套一个匿名结构体的,这种结构体呢,也可以直接指定匿名结构体的各个字段的值,那怎么指定呢?有这么几种形式,对吧?
28:03
呃,就是这样的形式,大家看这里。就是第一种形式按顺序写,第二种呢,就是按前面写字段名,后面给值也可以付,还有呢,就是有些程序员呢,他喜欢在继承的时候啊,他就直接怎么样呢,把这个类型的指针,指针类型给你放到这里面去也是可以的,那么在创建的时候呢,要注意它的细节是要给地址好吧,那关于当然更多的还是用的上面这种啊,上面这种用的更多一点啊,一般我们是使用上面这种。好,同学同学们,那关于继承的这个细节呢,老师就给大家介绍这里,那后边呢,我们就要准备做一些课程练习题了啊,那关于继承的细节,我们就给大家全部介绍完了,大家把这六点掌握好,基本上在我们做开发的时候是足足的够了。
我来说两句