00:00
接下来我们再介绍一个重要的概念,叫做循环不长啊,那循环不长这个概念其实主要是针对范围便利而言的,其实之前我们在范围便利考察它的底层源码的时候也已经发现了,呃,在rich int里边,我们调用它的n until或者调用to方法的时候,我们会看到传进来的参数是只有两个,Self和end,那最后创建range的时候呢,相当于就是只有它的start和end嘛,那其实最终我们去new一个range的时候,它还有第三个参数,第三个参数。那就叫做step,这个就是所谓的循环不长啊,那所谓的循环不长什么意思呢?其实简单来讲就是我当前定义了范围是多大。那么当前的循环变量当然就是在这个范围内要取数了,那我这里面的取数一到十,那当然就是一二三四五六七八九十,每一个都取变,这是我能够想到的,这是默认的情况,那我能不能直接隔一个取一个,隔一个取一个,跳着取里边的数呢?那其实这个是可以的,这就是所谓的一个循环不长的问题,那默认情况下为什么是所有的都可以取到呢?那这就是我们在这里直接调用的时候,听到了传进来的循环不长,其实就是一嘛。
01:23
这就相当于我们在Java里边不是有一个爱加加这样的表示吗?每一次都加一啊,所以这里边其实就是范围便利的时候默认就是加一啊,所以当前如果说我们想要让它跳的步子大一点,每次都隔一个取一个的话,哎,那我们可以把这个步长改成二不就可以了吗?哎,这是一个非常简单的想法,那我们看一看在当前的这个for推导式里边到底怎么来实现了,我们还是先把分前的分界线打印出来。接下来是第四部分循环不长,那这里面我们如果要去直接定义这个循环不长的话,其实也是非常简单啊,语法是非常简单的,其实就是先把基本的,所以老师写出来一。
02:18
不值方说我们现在想要从一开始啊,只取奇数13579,那应该怎么取呢?后边加一个不长的定义,哎二就是每隔一个取下一个,那大家知道就相当于每一次是I加二嘛,哎,所以就是13579,所以这里边我们用一个BY来做了一个不长的定义,哎,来把这个I打印出来,我们看一下现在是不是真正意义上就是13519。没有问题对吧?哎,这是完全可以做到的,呃,那这里面大家可能会发现了,那这个拜到底又是个什么东西呢?弹进去的话,你会发现它也是一个方法,不过它是R里边的一个方法,哎,因为大家想到前面1TO10这定义的不就已经是一个range了吗?哎,所以接下来你如果再调用的话,后边是不是就是相当于可以看到啊,前面这一部分,如果我们已经把它作为一个整体的话,后边再去调用的话,其实是这样的一种方法调用。
03:23
呃,Range的方法,然后大家看到它其实就是直接做了一个copy,那copy这个方法的话,显然它是要重新用一个range了,然后传入当前的start and和step,那step是什么呢?就是当前传BY传进来的这个参数,所以就把我们range本身定义的这个step根本又指定清楚了,如果不指定的话,默认当然就是一了啊,所以这里边其实就是这样的一个实现啊,那一般情况下我们不需要这么麻烦啊,方法调用,直接把它用空格空开,后边的参数只有一个可以省略括号,那这样的话我们看到这就像一个完整的英文表达一样啊,就是一到十,然后呢,每隔两个取一个数。
04:09
然后取到的就是所有的基数了,所以这个其实简单来看的话,还是非常的容易实现的,呃,那另外大家可能会想到,如果要这么说的话,呃,那当前的这个范围是取多少,然后跳几个都可以吗?哎,确实是这样的啊,比方说我们在这里边还可以和一个其他的N取,比方说我从稍微的奇怪一点,我从13开始取13举到30,然后呢,哎,三这样也是完全可以的,然后打印一个print line。前的这一个元素啊,里边我们在第四步内部,我们就用一个单画线把它做一个分割吧,然后大家看现在我的步长是三,从13取到30,诶所以大家看到其实就是从13开始,每一次下一个取的都是加三之后的值对吧?哎,那一直加到28,再加三三十一,超过30了,那就没有了,诶所以这个其实还是非常好理解的啊呃,那那接下来有同学可能就想到了,那我们前面指定的这个步长都是都是大于零的。
05:22
那能不能不长小于零呢?诶,这里面确实是比较有趣的一个一个用法啊,如果说这里边我们要做一个不长小于零的话,我干脆直接把这个做一个copy。如果这里边我们直接给一个负二的话,那会出现什么情况呢?直接运行。大家其实能够想到,按照我们之前的分析,从13开始,每一次都加上步长,按那来看,这个一加,那不就加加回去了吗?对吧,就变成13减二变成11了嘛,那不就相当于永远达不到这个30这个结果了吗?哎,所以这样的话,我们当前便利其实相当于是不成立的,就直接没有任何的输出了,那怎么样才可以有对应的输出呢?啊,这个很容易想到,如果我们定义的起始start比结束end要大的话。
06:15
然后我们做一个递减,做一个负的步长不就可以了吗?哎,所以接下来我们可以30~13这样去做一个定义,现在就可以真正的输出了。我们可以看到倒叙输出30开始,每一次都减二,28 26,一直到14,再减二的话,减成12,哎,那就超出13范围了,所以就没有了啊,所以负数其实也是可以做到的啊呃,那有了这样一个考虑,其实我们就可以反到我是不是可以直接比方说这个从一到十,我可以直接完整的做一个遍历,那假如说我要做一个倒序的遍历,从十到一能做到吗?哎,其实这个很简单,是不是直接直TWO1,然后step再给一个负一就完事了呀啊,所以整体来讲的话,这个实现是还是很简单啊,就可以实现这个倒叙,当然对于这个scla而言啊,For推导式,它其实还有另外一种实现方式。
07:16
就我可以本身用这种方式是完全没有问题的。但是有时候呢,能友觉得这个BY负一有点奇怪,那我还是可以把它写成从一到十籍贯的这种正序便利的方式,只不过呢,后边再来一个reverse reverse大家知道就是反转的意思嘛,这样的话,如果直接呃去执行,同样也是把它反转之后从十到一的一个运行结果。其实点到源码里边,大家会发现啊,源码里边它其实就是呃,当前的这一个,你看new了一个新的range.inclusive然后把这个起始和结束反转过来,然后step做了一个负号,加了一个负号,其实就是我们所谓的11,然后给一个负一的补偿嘛。
08:05
本质是一样的啊啊,这就是关于这个。范围便利做这个反转便利的一个用法啊,其实用布长可以解决,这里还有一些特殊的用法,大家可能会想到,哎,那你既然是有正有负,那这个不长可以是零吗?需要注意一下啊。我们还是直接复制一下前面的这个结果,大家要注意,如果这里边给了零的话,直接运行,那就会出现问题了,那直接会报一个异常出来,那这个异常它抛的是。大家看这个提示的信息啊,就是不长不能为零,哎,这到底是在哪里定义的呢?其实在range里边我们可以看的非常的明确,我们可以直接搜一下这个这句话啊。这个源码里边直接搜索会看到是在一个所谓的count方法里边去定义出来的,这个方法里边呢,就是判断,如果不长为零,直接抛一场啊啊,那然后呢,他还要去做一个is empty的判断,他怎么判断呢?就是如果啊,就是start和and相等,而且呢,不包含and的话,当前它就是空,Is empty它就是空的,那另外还有什么情况下是空呢?呃,就是如果start比and要小啊,就是比方说从一到十对吧,从小到大,但是step是小于零的,是负数,那这就是我们前面说的,假如说正向的从小到大的一个范围,但是呢,Step给了一个负数,这个时候它直接判空,所以就不会有任何的输出了。
09:47
那同样反过来,如果要是start大于等于and,然后stop step又大于零,又是一个正数的话,就像我们一开始给大家做了一个测试,就这里边如果我们这个30图13,然后拜正二的话,那那相当于这里边也是一个也是一个一,Empty是被触的,所以最后就相当于没有任何的输出了啊,所以通过这个方法,大家也可以把这个底层的逻辑看得非常的清晰啊,啊,所以大家要注意。
10:18
这个我们住掉。Z能为零,当然有,还有一些同学可能会做进一步的思考,就是呃,既然我们可正可负,那我能不能,呃,就是前面我们是相当于每一次都是相当于一一步走走一格对吧?啊,每一次走一步,那之后我们把这个步长可以调大,可以变成一次走两步,一次走三步也可以呢,倒退对吧?负号就相当于是倒退回去嘛,一次退两步,一次退一步,那我能不能一次走半步呢?
11:02
哎,这个其实就会想到我的步长,能不能给一个浮点类型或者double类型的数呢?哎,这个其实也是可以的,我们可以做一个尝试,哎,如果要是从一到十,那我们拜0.5的话。可以吗?要注意直接这么写是不对的,为什么呢?这是因为大家还记得前面我们得到的是什么吗?我们调用的是reach in里边的n until和to的方法得到一个range,这里边我们是不是这个start and都是in呀?然后大家看这个range里边。你扭出来的这个range,它本身就是一成字的这个集合类型,它是有泛型的呀,泛型本身就要求里边的元素必须得是int,这里边的step是不是也必须指定必须是int呀,哎,所以这里边你的这个不长,不能给这个0.5,不能给double类型,那怎么办呢?是不是就不能实现呢?其实可以啊,我们在你前面是reach int这样定义不长,不能定义double类型,那假如说之前我这里边就是一个比方说是reach float或者reach double的话,那是不是就可以了呢?哎,所以其实这是一样的啊,那怎么样定义一个rich ink或者reach double类型的的一个呃,一个范围呢?呃,其实也非常简单,大家看,就是把前面我们的范围定义的时候,定义成1.0~10.0,诶,这不就可以了吗?可整体来讲的话,就是把这个定义成一个double类型的。
12:40
运制,然后再BY0.5这样就可以了啊,当然大家看到这个to的话,这里边是已经要被弃用了啊dere kid推荐的是什么呢?推荐大家用big decim啊,这主要就是因为我们平常使用的这一个float或者double类型是有有可能出现精度缺失的啊,Big的话就不存在这个问题对吧?啊,当然这里边我们只是实现功能的话,这个其实是没有影响的啊那了啊,那我们把这个I做一个打印啊,当然这里大家如果想用I再做一个实现的话,我们可以把它叫做data啊。
13:17
看一下应输出的是什么样子。看这就是一次迈半步,0.50.5的增长对吧,1.01.52.02.5,一直到最后的10.0能够包含。啊,当然这里边如果说我们不是拜0.5而是拜0.3的话,大家就会看得比较明显啊呃,这里边大家看到这个精度就出现问题了啊,在有些场景下,比方说我们本来应该是3.1,这里边输出的是3.09999996对吧,甚至有可能最后大家看甚至有可能会超出十去诶,所以在有些场景下,确实是用这个直接用这个double类型是不太好的一种方式啊,推荐大家用big de啊,在这里边我们只要知道怎么样定义不长就可以了啊,这是关于循环不长的一个使用。
我来说两句