国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

條件表達(dá)式的短路求值與函數(shù)的延遲求值

2019-11-14 13:41:46
字體:
供稿:網(wǎng)友

延遲求值是 .NET的一個(gè)很重要的特性,在LISP語言,這個(gè)特性是依靠宏來完成的,在C,C++,可以通過函數(shù)指針來完成,而在.NET,它是靠委托來完成的。如果不明白什么是延遲求值的同學(xué),我們先看看下面的一段代碼:

      static void TestDelayFunction()        {            TestDelayFunton1(true,trueFun3);        }        static void TestDelayFunton1(bool flag , Func<bool> fun  )        {            if(flag)               fun();        }

在方法  TestDelayFunton1 中,函數(shù)型參數(shù) fun 是否求值,取決于第一個(gè)參數(shù)  flag,如果它的值為false,那么函數(shù) fun 是永遠(yuǎn)都不會(huì)被求值的,所以,這里函數(shù) fun的求值被推遲到了方法TestDelayFunton1 的內(nèi)部,而不是在參數(shù)計(jì)算的時(shí)候。

延遲求值很有用,它可以避免我們無謂的計(jì)算,比如上面的例子,這樣可以節(jié)省計(jì)算成本,假如 fun的求值很耗時(shí)的話。

我們注意這一段代碼:

if(flag)   fun();

 

其實(shí)它等價(jià)于一個(gè)邏輯表達(dá)式:

bool result= flag && fun();

在這個(gè)表達(dá)式中,fun() 函數(shù)是否求值,取決于變量 flag,這個(gè)功能叫做“短路”判斷,“條件短路”功能正好實(shí)現(xiàn)了我們的“延遲求值”的功能,因此,我們可以得到如下推論:

任何時(shí)候一個(gè)函數(shù)fun如果需要延遲求值,那么都可以表示成 一個(gè)條件表達(dá)式:

(Test() && fun())

所以,前面的2個(gè)函數(shù),本質(zhì)上可以改寫成下面的一個(gè)函數(shù):

      static void TestDelayFunton2(bool flag)        {            bool result = flag && trueFun3();        }

它將  TestDelayFunton1(true,trueFun3); 的形式調(diào)用,轉(zhuǎn)換成了上面的一個(gè)函數(shù)調(diào)用。

當(dāng)然,要讓這種調(diào)用變得可用,我們還需要解決一個(gè)問題,就是函數(shù) fun()的類型并不是 bool類型,這個(gè)問題處理很簡(jiǎn)單,將函數(shù)再包裝下即可:

bool WarpFunction(){  fun();  return true;}

之后的調(diào)用將是這個(gè)樣子的:

(Test() && WarpFunction())

對(duì)于本例,它其實(shí)等價(jià)于:

(flag && trueFun3())

 

如果是“聰明”的編譯器,它是可以完成上面的轉(zhuǎn)換的,下面給出一個(gè)完整的代碼圖片,這樣你能夠看得更清楚:

上面被標(biāo)記的部分的2個(gè)函數(shù),等價(jià)于下面這一個(gè)函數(shù),也就是說,TestDelayFunton1 的調(diào)用變換成了 TestDelayFunton2的調(diào)用。

 

如果你對(duì)上面的這個(gè)過程還是不太明白,那么我們看看下面這個(gè)例子:

 static bool trueFun1()        {            Console.WriteLine("call fun 1");            return true;        }        static bool falseFun2()        {            Console.WriteLine("call fun 2");            return false;        }        static bool trueFun3()        {            Console.WriteLine("call fun 3");            return true;        }

執(zhí)行下面的代碼,trueFun3都會(huì)被執(zhí)行么?

if (trueFun1() && falseFun2() && (trueFun3())){             } Console.WriteLine();if (trueFun1() || falseFun2() || trueFun3()){}

假如你非常理解C#的“條件短路”特性,相信答案很快就出來了。

 

閱讀完本文,你可能會(huì)問如此奇淫巧技,有何作用?

如果你深入研究.NET的委托,就會(huì)明白委托調(diào)用其實(shí)是將一個(gè)函數(shù)用對(duì)象進(jìn)行包裝,.NET自動(dòng)為你生成了很多代碼,性能上必然有所損耗,假如你在某些地方需要性能極致的代碼,那么本文這個(gè)技巧一定可以幫助你,假如你還能夠?qū)懗鲆粋€(gè)這種轉(zhuǎn)換的編譯器來,恭喜你,未來的大神就是你了!

 


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 涟水县| 金门县| 崇明县| 冕宁县| 海安县| 达日县| 永和县| 龙口市| 南丰县| 万山特区| 铅山县| 新田县| 柳江县| 河东区| 桐乡市| 句容市| 卫辉市| 乳山市| 响水县| 宾阳县| 大荔县| 丹江口市| 盖州市| 开平市| 历史| 牡丹江市| 临沧市| 台东市| 元氏县| 河北区| 永川市| 田东县| 红原县| 驻马店市| 丹江口市| 嵩明县| 昌宁县| 耒阳市| 和龙市| 临洮县| 承德县|