00:00
那么下一个要给大家讲的是什么呢?讲的是约束类还是类型约束上下文界定,这个呢,叫做context的棒,那么这个上下文鉴定,听这个名字呢,就跟我们这个整个这个。运行程序的这个上下文就是上下环境,它是有关系的,那么看这里。那这个与view棒子一样,上下文界定呢?它也是隐式参数的语法堂,这个语法堂就显得更高级了哦,更高级想看这好多同学前面说有看不懂的地方,就跟这个地方有很密切的关系。这面什么叫语法堂呢?以前老师讲过,语法堂就是它有时候本质是一样的,它是在形式上呢,让你要么就为了让你显得更方便一点,要么就是更更能够适应更多的应用场景,这个叫语法堂。那么在语法上的方便,它语法呢,就是为了为语法上的方便引入了上下文界定这个概念,本质变化并不大。
01:02
啊,也就说你学到现在,你一定要知道类型约束,我们讲的视图鉴定也好,还是这个上下文鉴定也好,它其实就是两点,一个是类型约束,第二个呢,它使用我们把我们前面讲的影视呃值啊,影视函数进行整理起来,前面我们已经用到了影视函数,但是没有用到隐视值,这里面呢,上下文界定就凸显了影视值的价值,我们来看看它是怎么用的。还是老规矩啊,咱们直接就上案例了,那么上下文建立呢,我这就一个案例,就能把这个事情讲清楚,虽然是一个案例,但是实际上我这有三种形式,看方式一,方式二,方式三,把这个理解了就到位了。好,我们先来看这个上下文界定应用案例的要求。第一,请使用上下文界定加影视参数的方式,诶,前面是视图界定加影视函数的方式,这又变了,变成隐式参数的方式,比较两个person对象的年龄大小,还是以它为例。
02:06
啊,但是要求使用order in实现比较,那么我要讲一下order in和这个order的区别。同学们啊,同学们前面在学这个基础的时候呢,对,你们在学这个基础的时候呢,应该学过这样一个东西,想看一下啊。就是呃,Order,我们先这样子啊,直接把这个拿出来看就行了。Order,我们前面已经有两个了啊,一个是order。大家看在这里,第三个案例里面呢,我们有一个第二个案例里面有个order的,大家看这个ordered呢,往看这有个order的,还有个order看这里。看这里啊,那么这个order和order区别在什么地方,区别在什么地方,我们先来看order的,Order的呢,它其实是实现了我的继承的一个接口。
03:01
既然是接口呢,往往是去重写或者是实现它的compare方法。那么到了这个地方,就是同学们看到这个order音呢,发生变化了,我们来看order音是什么进去它呢,是以这个继承的方式去写的这个compare comp是一个比较器,那么比较器呢和那个compare接口是它这个是写一个外置的一个对象来去实现这个方法,而刚才看到的那个compare接口呢,是重写这个方法来实现这个比较的,所以说我这里写了两句话,大家看一下就可以了,很简单啊,就担心。有同学被问到,啊,看order和ordering的区别,Ordering继承了Java中的comp comp这个接口,这个是个比较器,而order呢,继承了Java的compar这个接口。
04:02
那么在家中,Competor是一个外部比较器,需要定一个内来实现,而competor呢,是一个内部比较器,使用内内部这个重载,或者叫重写这个compare to这个方法,这就是他的一个区别。啊,就是说别人问到你呢,你就说一个是呃,要用外部,外部一个是外部比较器,一个是啊内部比较器啊,一个是重写或者重改方法,一个是写一个类来实现就可以了,好可以了,本质呃就是说都是为了实现,只是应用场景不一样,好现在呢,我们来玩一把。好,首先我要做一件什么事情呢?看啊,首先我在这里要这么去用,先把这个我们由简单往深入走啊,有简单往深入,那么新建。一个包啊,这个叫康。Context上下文bounce界定的一个DEMO啊,一个上下文Bo,那么我在这里呢,新建一个文件啊,那就是context上下文B啊DEMO。
05:15
啊就一个,所以说我就不写那么多了。Object。好,我们有简单,我这边放代码啊,第一个这段代码我相信同学们都能看懂,这没有哪个看不懂的,建了一个person里面呢,有这么两个只读的属性啊,我也重写了它的图示顺方法。这个呢,重写,重写了一个图示顺,为了方便,第一个就说完了,这个相信同学们都能看懂,那么下面呢,我又写了一段代码啊,我写了一个什么呢?Compare com4这段代码呢,我们来看一下这种写法大家可能没有见过,没有见过,我们看第一个最简单的。OK,这呢,我写了好几种了。啊,每个都让他看一下,这个呢,是我们写的COMPARE4T ordering,说明我支持一个泛型。
06:05
我支持一个泛型,但是这个地方呢,我并没有去用这个什么上下这个这个这个符号,其他符号就是t order,然后这边传了一个两个。对象这个T呢,它是ordering的一个,就是他只要去实现了或者是继承的这个ordering就能传进去,那么这里面这个方法是什么呢?大家看这里啊,Implicit大家还记得这是什么吗?这是一个隐式参数,看到没有?这个地方是一个隐私参数,我做一个说明。做一个说明啊,其实这个呢,就是个语法糖。以前我们讲过的,前面这个是泛型,这个就不说了。这个是一个泛型,前面我们讲讲过好多遍了啊,这是一个泛型。然后呢,第二个呃,接受了这两个参数。接收了什么呢?接收。
07:00
接收这个T类型的。T类型的这个这个这个这个对象吧,T类型的对象,第三一个看这句话,这句话呢是一个影视。隐私的一个参数,就是将来在他的这个上下文里面,如果发现有这么一个order in t的这个实现了这种order in t的这么一个对象呢,就传进来,传给谁呢?传给这个compar。啊,这个是个影视参数,大家应该能看懂。啊,四。啊,是一个隐视参数,是一个隐视参数,那么到时间他会这个影视参数会怎么样呢?你看我这直接调了,在这里面我调用这个comp的compare方法去实现一个比较,当然你这个方法怎么。怎么去实现。你可以在。这个里面去写。好,这个第一种方式说完了,那么现在我们需要一个影视值。
08:01
没有影视值你是跑不起来的,那这个影视值我怎么写的呢?也非常简单,你看我在这写了一个这样的对象啊,待会呢,我在这写的啊,我就直接写到这一个地方就就不啰嗦了。这里面我写了一段代码。直接拿到这用就可以了。大家看这一点吧,应该能看懂。啊,应该能看懂这方我在。我在这定义个什么东西呢,往上看。啊,这地方我这里写了一个隐式值。这里我定义了,定义了一个影视值,这个影视值它是一个order in。里面泛型是person的一个啊,一个匿名子类啊,可以说是是一个子类啊,是那个实例,实例里面我重写一个compare方法。啊,这个影视值是什什么类型的,是这个类型。这个类型好,你看这个就写完了,写完过后我们来看怎么用它呢?诶这样就很简单了,你看相当于说这个比较器,它会自动的给你扔进去。
09:11
呃,同学们回忆一下这个隐,同学们回忆一下这个隐视值啊,隐视值和隐式参数的关系回忆一下。那么如果想不起来,我带大家回忆一下这个,我们回忆一下影是值,我们是在D。哪一章讲的是在第?往上走,应该是在这儿。影视值在这讲的,回忆一下隐视值什么意思,就是我在这有个隐视值,比如说是尊类型,我这里有个隐视参数。那么如果说我在这儿什么都没有传。什么都没传,那么编译器会在底层直接将你这个影视值给你装进去。你看这个地方就是隐私值嘛,啊,这个是隐私参数嘛。它会在上下一翻哦,这有个隐私值给你扔进去了。
10:02
其实这个地方我们就使用到了这个隐式值和隐式参数的方法,只是我这里呢更复杂一点而已,好这样有了过后那就简单了,我就溜一个这样的实例。好,同学们看,我就留一个这样实例,六个compare,然后呢,我就先先传两个,先传两个这个order in这个实现这个ordering的这个这个参数,那么person我就可以用一下了。啊,Person,因为person呢,呃,在传递的时候,我们把这个对象传进去啊,把两个对象传进去,好我们看看这个对象怎么传的呢,也非常简单啊,大家看我这里的代码。你看我这创建了两个person,这个我相信同学们都能看懂,代码特别的简单。往这儿一放就可以了。我就不洗了啊。我这儿。这是创建了一个学生。啊,创建了个人,哎,这个应该写成这个得改,不改到时候运行肯定跑不起来,改成PERSON4吧,不改跑不起来,待会。
11:03
全部改成四。那这一面我要改成四材系,不然的话,道行肯定跑不起来。改成四,全部改成四。四好,这个代码就这边就过了,这边也是四。好,这边也是四好大看这有一个person,这一个person,那我直接把PP二传进去了。诶,这样传进去就可以用了。这样传进就可,为什么呢?因为你传进去的时候,这个比较器也会被找到。比较去,那你他怎么知道你这个传进去的类型是实现order呢,因为你的影视影视这个参数里面是知道你order,你包了PERSON4的,所以说你才能用。那这个时候我们再来执行呢,这个时候一定会返回一个什么呢?就是史密斯这个信息就会被返回,那么我们来跑一下。运行一下。好,当我们运行过后呢,我们发现这个结果跟我们想的应该是一样的。
12:00
啊,但是你你看这样子,为什么你能看得懂啊再看。这个地方一个t order这边是一个影视的。隐式参数传来一个比较器,比较器是从这儿带过去的。好,这样子大家应该就看的比较清晰了。啊。啊,当然你前提是有这个啊,你要这个没有的话,肯定代码全错,你这个一旦注销了,你看。你你们来看一下,跑起来,你看你看会有什么后果。对吧,肯定直接就给你抛常了,他这就跑不跑不动了,因为他匹配不到嘛,他说这面找不到,找不到下面你这个肯定是跑不起来的,再有一个类型也不匹配了,你这个person跟他没有任何关系嘛,就是很普通的一个person。所以这个影视影视这个值呢,它的作用很很很大的,好,这是第一个调用方式,我们再来看第二种调用方式,第二种用方式,第二种方式呢,它是什么呢?方式二。方式二呢,有些程序员或者代码里面,他是把这个影视这一部分拿到里面去了。
13:03
直接扔到这里面也可以,这种语法呢,大家也要看懂,看这个语法我就直接说了啊,代码也并不难。这个代码呢,我在这儿给大家运用起来,方式二,这个方式二呢是将隐式参数放到方法体内。大家看,我给大家整理一下。再看我这么写的,还是前面这一部分,没有发生任何变化。没变化,只是这个gea,这个g a greater这个单词写错了,就哪个改了啊,就greater,那么你看这里面呢,我把这个隐式参数直接扔到这里面定义定义的一个方法。就是什么呢?我在这儿拿到一个compare,然后。本身原先写的这这个比较呢,我放到这儿去了。放到这去了,放到这儿去呢,我让他给我返回一个,呃,这个地方会返回什么呢?看这这个比较器,其实它反应的值是由这确定的。
14:00
啊,这个其实就是返回两个年龄,随大随小。这么会会返回一个什么呢?返回一个返回一个数。返回一个数值。数值啊,我慢点数字数字,那么零表示什么呢?零表示OE大于。O2反过来就就不一样了,你看这这两个O1和O2是这个比较器调用的比较器在哪里,进去看一下。在这这个方法被我干什么,被我重新写了,在哪写着呢,在这写的。在这儿写的。啊,说白了就是两个人,两个人的年龄,两个人的年龄,因为他他在这拿到了,好这边我调用过后呢,我这事如果。哎。就是如果F1返回的值大于零。就。就返回啊,就看什么,就返回这个OE。
15:00
啊,否则呢,返回对吧,返回O2完事了啊,多简单啊,这也就是相当于把这里面的东西扔到里边去,这种写法大家也要看懂,不然的话以后你会觉得,诶,怎么怎么怎么奇怪呢,只要看到这个东西,一定在上下文能够找到一个影视值,只是这个影视值呢,有可能是写到这的,也可能是引进来的,比如说人家在这没有写干什么呢?人家把它卡了,用一个音port引进来的也是有可能的。我这就简单直接写了一个,直接写到这了,好,这样写法呢,代码也很简单,我们还用P1和P2来玩啊,老规矩来跑一下。写个五。好,斜骨,然后这边调一下鼓。诶这样子,这样仍然返回私密室35那一样的效果是一样的,跑一下执行代码。二执行代码。我们看看这个执行的代码跟我们想的是不是一样的呢?仍然一样好,这是第二一种方式,还有第三种方式更有意思。
16:03
方式三。方式上也是我们在SPA或者元代里面看到的一种方式,这个叫很有意思的语法堂现象。看这。这个代码呢,我直接拿出来大家看一下啊,这种写法。这种写法特别有意思,他是怎么写的呢?这样写的。哦,件代码我拉过来。方式三这个是什么呢?COMPARE06也是t order这个前面这个一样的,里面呢,我怎么写的,也写了一个方法,Greater。那么这个地方我怎么写呢?直接大家看。用。然后order in t这种写法很少见,对吧?这个时刻这句话就是写的这句话会发生一个隐私转换,它会获取到哪个呢?会获取到我们的这一个。你是指?那我先来给大家看一下这个一式是不是啊,我在这里为了好看呢,我把它哈希一直打出来,刚才我们看一下这个这个这个转换器的地址。
17:08
就这个地方,说白了这句话。就会把你当前上下文的一个order in t这个类型交给。这个变量它的地址,看一下它的哈希值。哈希。哈希code我们来打出来,请看代码。compare.code。好,既然我在这儿拿到那个比较器,我当然就能调这个比较器的方法。Compare,我要ou运算,如果大于零怎么办?不大于怎么办?这是使用的一个,呃,Implicity的一个语法糖,最简单。这个是最简单的一个写法,那么推荐使用啊,比前面那个呃,看起来更更简洁一些,好好,这个方法呢,我们再来用一下,怎么用老规矩啊,在这儿我们写一个。
18:00
六。266。六。再来这来一个六。好,那现在呢,我们来证明一下这个事情啊,先看这个结果对不对,先看这个结果对不对,这个结果呢,一跑发现代码应该也是正确的。而且大家看我在这个地方。通过这个隐私转换,我拿到这个比较器的地址是这个值,那我现在来证明一下,这两个比较器是同一个。怎么看呢,咱们可以在这个地方。把它打出来看一下,就是这儿不是已经有一个比较期了吗?我们来把它打出来看一下在哪打呢。啊,我们看在哪打比较合适啊。这个地方。呃,拿到了在哪打比较合适呢?这样子我就直接在主函数里面打。哦,我直接用。啊,对吧,我们说一下这个这个person comp的它的一个哈西code。
19:00
他们是不是同一个呢啊哈希code等于加上我们这一个啊person。诶,写错了,Person的哈西扣,我们看是不是同一个。好,这有个哈扣。到了这里面,到这个compare里面呢,也有一个,呃,用语法堂得到的哈西扣这两个比较一下,看看是不是同一个比较器,好我们来运行一下啊,同学们运行。好,当我们运行完了过后呢,我们可以看到这两个地址是完全一样的啊,你看外面那个哈西code的和你得到的哈西code的是同一个,因此呢,其实就是语法堂的一个作用啊,它这边相当于说做一个语法堂的一个转换,那么因为这个呢,如果同学们有兴趣可以往里面追一下这个原代码,其实很简单,它底层是怎么做的呢?就是这边有一个呃,有一个这个隐私值过后。他在他在这个编译的时候,他在编译的时候就直接把你那个。
20:05
呃,那个比较器直接就给它绑定到这个词上去了,编译器会做很多工作啊,这里面底层呢,它其实底层。底层仍然仍然使用。使用什么呢?使用这个编译器,编译器来完成完成一个绑定和或者是叫赋值的一个工作。啊,扶植的一个工作好,没有什么神奇的啊,大家看感觉好像隔山打牛,其实你看我们前面讲了很多,这个影视其实说白了就是底层他去检查,检查到过就把它绑定起来,完事了。这个编译器做了很多工作,他不会是动态的啊,动态效率就太低了,直接就绑定了。好,这是关于什么呢?关于我们讲解的这个上下文。啊,这个界定的一个说法,再理解一下上下文,上下文就是说影视值在一个范围里面,我就会去自动匹配里面呢,一共有这么三种形式,第一种。
21:05
直接把这个影视纸写在参数里面,有点像函数颗粒化,而第二种呢,就是把这个影视纸往里面扔,往里面下沉,就可以用多个地方,也也就说你在这儿可以用到,你如果还有别的方法呢,说老师,我这个除了要比较大小,我还要比较一个谁小lower。那lo里面呢,你仍然可以继续绑定我们这个东西,不是说只能绑一次。我仍然可以再放,只是呃,要反过来了,如果大于它,我返回它,如果大于这个才只就反过来了,如果是OO1大于它返回O2,就返回小的值完事了,这这一下就能解决。说以后你们看这代码呢,要一眼就看出他的这个东西,好同学们,那关于我们这个上下文界定的实例,老师就先介绍到这里啊,就走了一个实例。因为这个语法呢,咱们说往里面追太底层的这个一是没有必要,第二个就是,呃,确实是大家在开发中,你们更多的时间应该放在什么呢?业务逻辑,而不是语法本身,只要能看懂。
22:13
就可以了啊,其实这个也不深奥,就是编译器做了一个包装,编译器上来以后,他一发现这有个语法堂,直接给他绑定就完了。没有,多么神奇的事情啊,同学们。啊,不要觉得好像,诶,怎么这么神呢?一点都不神奇对吧,那么我把这个呢,给同学们进行一个板书,好,我往下面拉。好,这个地方有一个问题。好,我把这个写成正文,好,下面呢,我们这讲了往下走。讲了一个什么呀,讲了一个上下文界定对吧,上下文界定。小。上下文接地。诶,这个东西怎么。怎么往下拉不下来了呢?
23:00
好,上下文界定来走一个上下文界定的一个一一个这个案例我们来说一下好。上下文接地。先做了一个基本介绍啊,类型约束之上下文界定好,把这个说一下。那么这个呢,给他一个标题二。啊,像讲的上下文界定。然后商家文鉴定,呃,我们说的是什么呢?先做了一个基本介绍。啊,现在大家大家再回头看这个基本介绍呢,就感觉比较清晰了,就说白了,上下文鉴定是一个隐式参数的语法堂,就这么一句话啊,它就是饮食参数的一个语法堂。啊,然后呢,这边我们讲了一个案例,加深对它的一个认识,就是上下文鉴定的,呃,上下文鉴定的一个案例,对吧。啊,上鉴定案例,给他来一个标题三。那这里呢,我有什么要求,我就写到这了,两个要求,第一个用上元鉴定加隐私参数的方式来解决的好,然后呢,我们这个代码就写到这就可以了。
24:05
啊,代码就这么一截儿。啊,Content。三种形式啊,能看懂以后。给大家放到这一栏。诶,拿一个小表格。好,同学们,那关于上下文界定,我们就先讲到这里,截取一段视频。
我来说两句