駁「反駁老趙之「偽」遞迴」

2021-09-05 21:35:04 字數 1310 閱讀 4324

晚上看到鶴沖天的「反駁老趙之「偽」遞迴」,大概看了一下,主要是反駁老趙提出的「偽」遞迴的概念,特別是「偽」,看起來說的都很有道理,但我個人認為,老趙說的沒有錯,lambda這種看上去是遞迴的方式,根本不算是遞迴。

我引用鶴沖天的遞迴概念:

乙個過程或函式在其定義或說明中又直接或間接呼叫自身的一種方法

我覺得這句話說的很明白,通俗點就是自己呼叫自己,鶴兄說遞迴應該不僅僅是過程還是函式,應該包括匿名方法和lambda。我同意匿名方法應該算一種,但因為是匿名方法,我們在開發中無法知道方法名,故我們無法去呼叫它,但lambda(和委託)算不算一種遞迴呢?

我們都知道lambda構建的是乙個委託,委託只是對乙個方法的應用,lambda表示式只是構建了乙個匿名方法體,並沒有去執行,只有在使用的時候根據需求來延遲載入,但其中是有陷阱的,老趙先前寫了一篇「.net中*延遲*特性的幾個陷阱」,其中介紹的非常清楚。那如何反駁鶴兄呢?從他的程式來講吧。**:

public static readonly 

func

fac = x => x <= 1 ? 1 : x * fac(x - 1);

static void main(string args)

為了看清楚些,我索性執行了,照鶴兄所說,fac呼叫了fac就應該屬於一種遞迴形式,但你知道它其中執行了什麼嗎?look 反編譯:

internal class 

program

這樣我們能清楚些,當我們執行委託的時候,會使用invoke(args)來呼叫方法體,看清楚,是invoke方法,並不是委託自己哦,這一點已經偏離了遞迴的概念了。

再來看下我們原先的遞迴方法:

static int  fac(int i)

反編譯的**:

private static int fac(int i)

大家看清楚了吧,呼叫的是它自己哦。

繼續說鶴兄的**,就算鶴兄說委託呼叫自己委託屬於一種遞迴,但存在著乙個「延遲特性的陷阱」,這一點老趙已經說明,每一次呼叫的是方法體,其中的引數是從外部傳進來的,並不是方法自身往下傳的,老趙也在「使用lambda表示式編寫遞迴函式」進行了敘述,什麼意思呢?就是我們在委託呼叫委託的時候,「遞迴」還沒有結束的情況下,如果改變了外部這個引數值,就會影響到「遞迴」的結果,這也是閉包的乙個陷阱。鶴兄用了readonly來讓委託唯讀,想以此來構造乙個遞迴的委託,但真正需要繫結的不是方法體,還需要繫結引數的,你的引數值能通過外部進行改變的,而在傳統遞迴中,第二次呼叫的時候,引數值都是第一次呼叫說傳入的,外部是無法改變的,這一點是最能說明問題所在的。

選舉DR BDR 老趙網路

選舉dr bdr 這個問題很多人會迷糊,因為ospf協議複雜,這個選舉還要從學生的問題出發,乙個三個路由器的拓撲選舉出兩個dr,這個問題看起來很不正常,你耐心看完我的解析,你就覺得正常了!以下來自我的微信 51net 我們今天直接了當點,先普及下ospf協議中的網路型別 網路型別 hello時間 選...

路由重發布 老趙網路

1 配置位址 2 配置ospf路由 3 配置rip 4 r3上配置靜態路由目標網路192.168.6.0 下一跳192.168.4.2 5 配置ospf重發布到rip 中 6 配置rip重分布到ospf中 7 重發布直連路由到rip 和ospf 中去 8 重發布靜態路由到rip和ospf中去 9 重...

老趙書託(1) 寫在前面

最近我思考和總結地越來越多,感覺也是時候把自己許多年來的經驗進行一番總結和整理。談基礎與能力的時候,我把人腦比喻為 儲存器 裡面存放了 知識 和 能力 等資訊。而思考和總結便可以看作對這些資訊的索引進行整理,好比資料庫在執行一定時間之後需要整理索引碎片一樣。因為種種原因,一些重要的內容可能已經淡忘了...