成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Scala學習:傳名參數by-name parameter

開發 后端
本文節選自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻譯的《Programming in Scala》的第九章。Scala是一種針對 JVM 將函數和面向對象技術組合在一起的編程語言。

上節展示的withPrintWriter方法不同于語言的內建控制結構,如if和while,在于大括號之間的代碼帶了參數。withPrintWriter方法需要一個類型為PrintWriter的參數。這個參數以“writer =>”方式顯示出來:

  1. withPrintWriter(file) {  
  2.  writer => writer.println(new java.util.Date)  
  3. }  

然而如果你想要實現某些更像if或while的東西,根本沒有值要傳入大括號之間的代碼,那該怎么做呢?為了解決這種情況,Scala提供了傳名參數。

51CTO編輯推薦:Scala編程語言專題

為了舉一個有現實意義的例子,請設想你需要實現一個稱為myAssert的斷言架構。你只能稱其為myAssert,而不是assert,因為Scala提供了它自己的assert,將在14.1節描述。myAssert函數將帶一個函數值做輸入并參考一個標志位來決定該做什么。如果標志位被設置了,myAssert將調用傳入的函數并證實其返回true。如果標志位被關閉了,myAssert將安靜地什么都不做。

如果沒有傳名參數,你可以這樣寫myAssert:

  1. var assertionsEnabled = true 
  2. def myAssert(predicate: () => Boolean) =  
  3.  if (assertionsEnabled && !predicate())  
  4.   throw new AssertionError  
這個定義是正確的,但使用它會有點兒難看:

  1. myAssert(() => 5 > 3)  
你或許很想省略函數文本里的空參數列表和=>符號,寫成如下形式:

  1. myAssert(5 > 3// 不會有效,因為缺少() => 
傳名函數恰好為了實現你的愿望而出現。要實現一個傳名函數,要定義參數的類型開始于=>而不是() =>。例如,你可以通過改變其類型,“() => Boolean”,為“=> Boolean”,把myAssert的predicate參數改為傳名參數。代碼9.5展示了它的樣子:

  1. def byNameAssert(predicate: => Boolean) =  
  2.  if (assertionsEnabled && !predicate)  
  3.   throw new AssertionError  
代碼 9.5 使用傳名參數

現在你可以在需要斷言的屬性里省略空的參數了。使用byNameAssert的結果看上去就好象使用了內建控制結構:

  1. byNameAssert(5 > 3)  
傳名類型中,空的參數列表,(),被省略,它僅在參數中被允許。沒有什么傳名變量或傳名字段這樣的東西。

現在,你或許想知道為什么你不能簡化myAssert的編寫,使用陳舊的Boolean作為它參數的類型,如:

  1. def boolAssert(predicate: Boolean) =  
  2.  if (assertionsEnabled && !predicate)  
  3.   throw new AssertionError 
當然這種格式同樣合法,并且使用這個版本boolAssert的代碼看上去仍然與前面的一樣:

  1. boolAssert(5 > 3)  
雖然如此,這兩種方式之間存在一個非常重要的差別須指出。因為boolAssert的參數類型是Boolean,在boolAssert(5 > 3)里括號中的表達式先于boolAssert的調用被評估。表達式5 > 3產生true,被傳給boolAssert。相對的,因為byNameAssert的predicate參數的類型是=> Boolean,byNameAssert(5 > 3)里括號中的表達式不是先于byNameAssert的調用被評估的。而是代之以先創建一個函數值,其apply方法將評估5 > 3,而這個函數值將被傳遞給byNameAssert。

因此這兩種方式之間的差別,在于如果斷言被禁用,你會看到boolAssert括號里的表達式的某些副作用,而byNameAssert卻沒有。例如,如果斷言被禁用,boolAssert的例子里嘗試對“x / 0 == 0”的斷言將產生一個異常:

  1. scala> var assertionsEnabled = false 
  2. assertionsEnabled: Boolean = false 
  3. scala> boolAssert(x / 0 == 0)  
  4. java.lang.ArithmeticException: / by zero  
  5.  at .< init>(< console>:8)  
  6.  at .< clinit>(< console>)  
  7.  at RequestResult$.< init>(< console>:3)  
  8.  at RequestResult$.< clinit>(< console>)...  
但在byNameAssert的例子里嘗試同樣代碼的斷言將不產生異常:

  1. scala> byNameAssert(x / 0 == 0)  
責任編輯:book05 來源: Artima
相關推薦

2009-07-22 07:43:00

Scala重復參數

2020-11-24 08:45:04

Active Choi

2009-11-16 17:04:46

Inside Scal

2009-07-22 07:47:00

Scala客戶代碼

2009-07-21 16:58:31

Scala變量范圍

2009-07-22 07:43:00

Scala閉包

2009-07-22 07:53:00

Scala無參數方法

2009-07-22 09:02:45

Scala組合繼承

2009-07-08 15:35:18

Case類Scala

2009-07-22 07:57:00

ScalaCurry化函數

2010-10-27 16:14:24

Oracle參數查詢命

2009-07-08 09:47:49

Scala 2.8Scala

2009-07-22 09:22:20

Scala工廠對象

2009-08-03 11:07:18

Scala Actor

2009-07-09 00:25:00

Scala參數化

2009-07-20 16:56:51

Scala類的定義

2009-07-08 09:32:40

ScalaScala與Java

2009-07-22 08:34:47

Scala方法和字段

2009-07-08 12:43:59

Scala ServlScala語言

2009-07-09 01:48:10

Scala行記錄
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91欧美激情一区二区三区成人 | 我我色综合| 日本精品免费 | 日本一区二区不卡 | 国产精品v| 日韩中文不卡 | 在线成人www免费观看视频 | 久久久久亚洲精品 | 高清久久久 | 日韩国产一区二区 | 国产日韩久久久久69影院 | 伊人久久精品 | 亚洲欧美激情四射 | 夜夜骑综合 | 日日摸夜夜爽人人添av | 日韩精品一区中文字幕 | 国产精品日韩欧美一区二区 | 免费成人av | 中文字幕在线视频观看 | www.99热| 羞羞免费网站 | 日韩在线 | 久久性av | 台湾a级理论片在线观看 | 国产99精品 | 国产精品不卡视频 | 国产精品一区二区欧美 | 精品亚洲国产成av人片传媒 | 国产欧美三区 | 中文字幕国产在线 | 欧美中国少妇xxx性高请视频 | 无吗视频 | 91视视频在线观看入口直接观看 | 在线免费观看黄a | 国产一二三视频在线观看 | 亚洲一区中文字幕在线观看 | 国产探花在线观看视频 | 最新日韩精品 | 国产传媒毛片精品视频第一次 | 黄色片大全在线观看 | 欧美日韩国产一区二区三区 |