00:00
接下来呢,我们再来介绍一下skyla当中模式匹配的另外一个重要用法,那就是匹配对象,这个可以说是一个非常强大的功能,我们首先先来想一下,回顾一下之前我们讲的能够匹配的有哪些东西呢?我们可以匹配常量,可以匹配类型,还可以定义模式首位,然后去匹配一个范围,定义一个条件。此外呢,我们还可以去匹配,按照元组去做匹配,按照列表数组这种集合类型去做匹配。但是我们之前好像从来没有过能够去匹配某一个类的对象实例,比方说像现在我们定义一个user,或者定义一个student,啊,里边有两个属性,Name和age。我们给定创建一个对象实例之后,它里边肯定就有对应自己的名字和年龄了,那现在我怎么样能判断当前的这个对象实力,它的名字和年龄内容是否是我们想要的那个呢?哎,比方说我能怎么能判断当前这个user,他就刚好是爱丽丝18岁呢?
01:11
哎,这样的话,我们就相当于要做一个对象内容的匹配了,按照我们之前的想法,诶,那应该就是定义出来类,然后我们创建出来对象,然后match case,判断它的值刚好等于某一个具体的对象值,应该就可以了,那接下来我们尝试一下,看看能不能这么做。还是在下边新建一个SC的object s04下来我们主要是测match object没方法写出来,呃,那当前我们既然是要以被。对象实例,那肯定要先定义一个类吧,我们这里还是定义student类吧,特别熟悉的学生类,直接把它的属,我们现在其实并不需要考虑它的方法,我们主要关心的就是内容相同,那就是属性了,直接定义在它的主构造器里边加上V,就相当于把属性也直接声明出来了,Name the stream。另外定义一个age ins里面没有方法,那你就定义好了,下来我们就直接去创建的一个对象。
02:24
Student啊,New,一个student里边我们传一个name Alice,一个年龄18岁,然后接下来呢,那我们自然就是要针对。对象实例啊,内容进行匹配,既然是内容进行匹配,那我们感觉这个有点像之前,呃,不能说是匹配常量值,但是我们感觉好像是一个值的匹配,所以我们直接就照之前那个写法来列出来,第一个result student开始match case。
03:04
Case的时候呢,这里边我们自然想到了,那就是直接再去new一个student呗,我们把这个直接copy过来,同样内容name和age的student把它创建在这,然后如果要是匹配的上的话,我们就说是ALICE18,那如果要是其他情况的话,那就是貌,这个其实非常容易想啊,但是我们会发现当前的语法报错的。能直接这么去谬一个对象实例出来,因为该按照我们之前的那种想法的话,那应该这里放的是一个具体的常数值,或者是一,是一个已经是完全现成的对象,已经存在的对象,就像我们呃,某一个常数值,一个一,一个零,我们也可以认为是一个int类型的对象,或者前面我们在匹配的时候呢,也可以直接。
04:05
也可以直接有一个。有一个list啊,它的一个状态放在这儿,或者是一个啊,大家看到这个列表或者是一个数组,直接把它利用伴生对象创建出定义出一个具体的对象的类型,这样我们也可以直接去做这样的判断,那像现在我们并没有这样的一个伴生对象去使用,而是直接拗一个对象实例的话,看起来不符合这里的。模式匹配的语法规则,哎,那所以我们自然就想到了,那是不是可以用半生对象去做一个处理呢?半生对象里边我们知道有一个apply方法啊,直接呃,后边伴生对象名称后边加小括号就可以调用在apply方法里边呢,也可以直接访问我们当前伴生类里边的所有属性和方法,哎,那直接我们创建一个伴生类的对象不就可以了吗?哎,所以接下来我们干脆就再定义一个伴生对象一半生对象object。
05:11
然后对应的名称必须完全一致,Student里面我们最关键的就是要定义一个apply方法,我们知道这个play方法其实是要创建对象的,所以需要的参数得传入,哎,那对应方程的。当然就是new了,一个student了啊,Name和age为参数传入,盗用主构造器。生成一个对象实例,哎,那所以现在呢,我们自然就想到了,那是不是直接把new去掉,用当前本身对象的apply方法生成的这个对象实例就可以做判断了呢?这个思路其实是对的,但是这里大家看到还是在报错,诶,我们看起来好像是这个导包没导入对吧?哎,但是如果我们真的要导包的话,你会发现也导不进来。
06:02
其实仔细看他的报错信息,你会发现它是说我们没有实现当前伴生对象里边一个特殊的方法,叫做only。其实这个大家也非常好理解,就是如果这里边我们直接把一个对象放在这儿,要去跟另外一个对象做匹配的话,那我们这里边判断的应该是它的对象引用啊。如果判断引用的话,那显然两个对象肯定是不同的引用,我们现在要判断的是内容,内容的话是不是我们必须得有一个方法告诉我当前这个对象里面的属性到底是什么东西,我要判断的是哪些对象里面的具体的内容,这样的话我们才能比对,也就相当于我们在apply方法里面,为什么它叫应用呢?这相当于是把传入的参数做了一个对象的构建。然后on apply呢,那就是要把对象拆解开来,拆出里边所有的属性,方便我们去做值的对比,这样的话我就能判断对象里面的内容到底相不相同了,哎,所以接下来我们其实就是要必须直线一个N派啊,这个名称也是底层给我们固定好啊,就叫这个名,那么用来对对象主定定行,开解开包,哎,把它一个一个都拆开做比对,所以我们把这个单独的再定义出来,On apply啊,这里大家要注意这个是小写的啊,里边当前的这个参数,但是要拆包,那自然应该是传入student了,我们现成的一个对象传进去,当前要返回的是什么呢?
07:55
返回的应该是我们拆出来的一组属性。所以我们可以用一个。
08:02
元组类型来表示,哎,但是这里边呢,假如说我们当前这个student本身就是nu,那又怎么办呢?那就相当于你拆的时候肯定有问题了呀,因为我们拆的时候一定是要c.name.h去做返回,如果是那样的话,那就直接抛异常了,所以我们要处理这种情况,这里边呢,用什么来处理?之前提到过的option类型会而也就是说如果是前student为none的话,我们就返回option里边,如果为空的话,我们返回的不就是no那个nu吗?哎,这样的话就可以解决一个空指针异常的问题,里边的一类型我们当前就是一个二元组,一个string,一个in,里边具体的实现当然就是做一个判断当前的student,看是否为空。如果没空的话,那我们直接返回一个,那这是一个option类型,那另外如果不为空的话,返回的是一个萨,而且要把该解出来的属性包装成一个二元组的一个返回,哎,那我们这里面就是student。
09:18
An name student'an age哎,这样的话我们就可以得到具体的。我们当前每一个拆解出来的属性到底是什么了?哎,这就是我们想要得到的东西,那大家看,实现了on apply方法之后,现在这个语法就正确了,我们可以来运行一下,看看当前result是否是爱丽丝18没有问题,匹配成功,那如果我们这里换成一个BOB18呢?不然成了艾斯了,这是其他人了啊,甚至我们会发现,如果爱丽丝长了一岁,变成了19岁的爱丽丝的话。
10:01
对应的这个匹配当然也就不成功了,这已经不是18岁的爱丽丝,这就是我们所说的用模式匹配的方式去匹配一个对象的内容。
我来说两句