麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

條件表達式的短路求值與函數的延遲求值

2019-11-14 13:41:46
字體:
來源:轉載
供稿:網友

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

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

在方法  TestDelayFunton1 中,函數型參數 fun 是否求值,取決于第一個參數  flag,如果它的值為false,那么函數 fun 是永遠都不會被求值的,所以,這里函數 fun的求值被推遲到了方法TestDelayFunton1 的內部,而不是在參數計算的時候。

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

我們注意這一段代碼:

if(flag)   fun();

 

其實它等價于一個邏輯表達式:

bool result= flag && fun();

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

任何時候一個函數fun如果需要延遲求值,那么都可以表示成 一個條件表達式:

(Test() && fun())

所以,前面的2個函數,本質上可以改寫成下面的一個函數:

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

它將  TestDelayFunton1(true,trueFun3); 的形式調用,轉換成了上面的一個函數調用。

當然,要讓這種調用變得可用,我們還需要解決一個問題,就是函數 fun()的類型并不是 bool類型,這個問題處理很簡單,將函數再包裝下即可:

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

之后的調用將是這個樣子的:

(Test() && WarpFunction())

對于本例,它其實等價于:

(flag && trueFun3())

 

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

上面被標記的部分的2個函數,等價于下面這一個函數,也就是說,TestDelayFunton1 的調用變換成了 TestDelayFunton2的調用。

 

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

 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;        }

執行下面的代碼,trueFun3都會被執行么?

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

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

 

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

如果你深入研究.NET的委托,就會明白委托調用其實是將一個函數用對象進行包裝,.NET自動為你生成了很多代碼,性能上必然有所損耗,假如你在某些地方需要性能極致的代碼,那么本文這個技巧一定可以幫助你,假如你還能夠寫出一個這種轉換的編譯器來,恭喜你,未來的大神就是你了!

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 日韩每日更新 | 91精品欧美一区二区三区 | 国产精品久久久久久久四虎电影 | 久久精品久久精品国产大片 | 国产精品午夜未成人免费观看 | a视频在线免费观看 | 亚洲第一页中文字幕 | 亚洲第一视频 | 欧美一级一片 | 国产亚洲网| 茄子福利视频 | lutube成人福利在线观看 | 免费看日产一区二区三区 | 久久久久久久久亚洲精品 | 国产精品一区二区三区在线播放 | 羞羞的视频在线 | h视频免费看 | 99最新网址 | 免费毛片随便看 | 偷偷草网站 | 欧美h版电影在线观看 | 一本到免费视频 | 欧美精选一区二区 | 一区二区三区在线观看国产 | 精品久久久久久久久久久久久久 | 成人免费观看在线视频 | 国产真实孩交 | 久久久www视频 | 精品国产精品久久 | 看毛片免费 | 青青草成人免费视频在线 | 国产精品一区二区三区在线播放 | 久草在线视频网 | 97中文 | 日日狠狠久久偷偷四色综合免费 | 成人免费一区二区三区在线观看 | 国产成人精品区 | 欧美hdfree性xxxx | 1级黄色毛片 | 亚洲成人福利网站 | 中文字幕网在线 |