91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Scala控制結構指的是什么

發布時間:2021-11-20 16:42:03 來源:億速云 閱讀:132 作者:柒染 欄目:編程語言

本篇文章給大家分享的是有關Scala控制結構指的是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

迄今為止,在此系列中,我們已經討論了 Scala 對生態環境的保真度,展示了 Scala 如何將眾多的 Java 核心對象功能合并在一起。如果 Scala 只是編寫對象的另一種方式,那么它不會有任何引人注意的地方,或者說不再那么功能強大。Scala 的函數概念和對象概念的合并,以及它對編程人員效率的重視,這些使得學習 Scala 語言比 Java-cum-Scala 編程人員所想象的體驗更加復雜、更加微妙。

例如,對控制結構(比如 if、while 和 for)使用 Scala 的方法。盡管這些控制結構看起來類似一些老的、還比較不錯的 Java 結構,但實際上 Scala 為它們增加了一些完全不同的特性。本月的文章是關于使用 Scala 控制結構時能夠期望獲得哪些東西的入門級讀物,而不是在制造許多錯誤(并編寫一堆錯誤代碼)之后,讓您冒著遭受挫折的風險去尋找差異。

修訂后的 Person.scala

Scala 能夠通過定義一些方法來定義 POJO,這些方法模仿基于 POJO 的環境所需的傳統 “getter 和 setter”。在這篇文章發表之后,我收到了 Bill Venners 發來的電子郵件,Bill Venners 是即將發表的正式的 ,Bill 指出了實現上述操作的一個更簡單的方法,即使用 scala.reflect.BeanProperty 標注,如下所示:

清單 1. 修改后的 Person.scala

class Person(fn:String, ln:String, a:Int)     {  @scala.reflect.BeanProperty  var firstName = fn   @scala.reflect.BeanProperty  var lastName = ln   @scala.reflect.BeanProperty  var age = a   override def toString =      "[Person firstName:" + firstName + " lastName:" + lastName +   " age:" + age + " ]"    }

清單 1 中的方法為指定的 var 生成了 get/set 方法對。惟一的缺陷是這些方法并不實際存在于 Scala 代碼中,因此其他 Scala 代碼無法調用它們。這通常不是什么大問題,因為 Scala 將對為自己生成的字段使用已生成的方法;如果事先不知道,那么這些對您而言可能是一個驚喜。

在查看了清單 1 中的代碼之后,最讓我感到震動的是,Scala 并沒有只演示組合函數概念和對象概念的強大威力,它還演示了自 Java ***發布之后的 30 年里對象語言帶來的一些益處。

控制是一種幻想

您將看到的許多奇怪的、不可思議的東西都可以歸功于 Scala 的函數特性,因此,簡單介紹一下函數語言開發和演變的背景可能非常有用。

在函數語言中,將越來越高級的結構直接構建到語言中是不常見的。此外,語言是通過一組核心原語結構定義的。在與將函數作為對象傳遞的功能結合之后,可用來定義功能的高階函數 看起來 像是超出了核心語言的范圍,但實際上它只是一個庫。類似于任何庫,此功能可以替換、擴充或擴展。

根據一組核心原語構建語言的合成 特性由來已久,可以追溯到 20 世紀 60 年代和 70 年代使用 Smalltalk、Lisp 和 Scheme 的時候。諸如 Lisp 和 Scheme 之類的語言因為它們在更低級別的抽象上定義更高級別抽象的能力而受到人們的狂熱追捧。編程人員可以使用高級抽象,用它們構建更高級的抽象。如今聽到討論這個過程時,它通常是關于特定于域的語言(或 DSL)的(請參閱 參考資料)。實際上,它只是關于如何在抽象之上構建抽象的過程。

在 Java 語言中,惟一選擇就是利用 API 調用完成此操作;在 Scala 中,可以通過擴展語言本身實現它。試圖擴展 Java 語言會帶來創建極端場景(corner case)的風險,這些場景將威脅全局的穩定性。而試圖擴展 Scala 則只意味著創建一個新庫。

If 結構

我們將從傳統的 if 結構開始 —— 當然,此結構必須是最容易處理的結構之一,不是嗎?畢竟,從理論上說,if 只檢查一個條件。如果條件為真,則執行后面跟著的代碼。

但是,這種簡單性可能帶有欺騙性。傳統上,Java 語言對 if 的 else 子句的使用是隨意的,并且假定如果條件出錯,可以只跳過代碼塊。但在函數語句中,情況不是這樣。為了保持函數語句的算術特性,所有一切都必須以表達式計算的方式出現,包括 if 子句本身(對于 Java 開發人員,這正是三元操作符 —— ?: 表達式 —— 的工作方式)。

在 Scala 中,非真代碼塊(代碼塊的 else 部分)必須以與 if 代碼塊中值種類相同的形式呈現,并且必須產生同一種類的值。這意味著不論以何種方式執行代碼,總會產生一個值。例如,請參見以下 Java 代碼:

清單 2. 哪個配置文件?(Java 版)

// This is Java  String filename = "default.properties";  if (options.contains("configFile"))    filename = (String)options.get("configFile");

因為 Scala 中的 if 結構自身就是一個表達式,所以重寫上述代碼會使它們成為清單 3 中所示的更正確的代碼片段:

清單 3. 哪個配置文件?(Scala 版)

// This is Scala  val filename =    if (options.contains("configFile"))      options.get("configFile")    else     "default.properties"

也就是說,Scala 編程人員通常應該*** val 結構,并在明確需要可變性的時候選擇 var。原因很簡單:除了使編程更容易之外,val 還能確保程序的線程安全性,Scala 中的一個內在主題是:幾乎每次認為需要可變狀態時,其實都不需要可變狀態。讓我們從不可變字段和本地變量(val)開始,這是展示上述情況的一種方法,甚至對最堅定的 Java 懷疑論者也是如此。從 Java 中的 final 開始介紹可能不是很合理,或許是因為 Java 的非函數特性,盡管此原因不可取。一些好奇的 Java 開發人員可能想嘗試一下。

盡管真正的贏家是 Scala,但可以通過編寫代碼將結果分配給 val,而不是 var。在設置之后,就無法對 val 進行更改,這與 Java 語言中 final 變量的操作方式是相同的。不可變本地變量最顯著的副作用是很容易實現并發性。試圖用 Java 代碼實現同樣的操作時,會帶來許多不錯的、易讀的好代碼,如清單 4 中所示:

清單 4. 哪個配置文件?(Java 版,三元式)

//This is Java  final String filename =    options.contains("configFile") ?      options.get("configFile") : "default.properties";

用代碼評審解釋這一點可能需要點技巧。也許這樣做是正確的,但許多 Java 編程人員會不以為然并且詢問 “您做那個干什么”?

val 與 var

您可能想更多地了解 val 與 var 之間的不同,實際上,它們的不同之處在于 —— 一個是只讀的值,另一個是可變的變量。通常,函數語言,特別是被認為是 “純” 函數語言(不允許帶有副作用,比如可變狀態)的那些函數語言,只支持 val 概念;但是,因為 Scala 要同時吸引函數編程人員和命令/對象編程人員,所以這二種結構它都提供。

已公開的 while 結構

接下來,讓我們來看一下 while 及其同胞 do-while。它們做的基本上是同一件事:測試一個條件,如果該條件為真,則繼續執行提供的代碼塊。

通常,函數語言會避開 while 循環,因為 while 實現的大多數操作都可以使用遞歸來完成。函數語言真地非常類似于 遞歸。例如,可以考慮一下 “Scala by Example”(請參閱 參考資料)中展示的 quicksort 實現,該實現可以與 Scala 實現一起使用:

清單 5. Quicksort(Java 版)

//This is Java  void sort(int[] xs) {    sort(xs, 0, xs.length -1 );  }  void sort(int[] xs, int l, int r) {    int pivot = xs[(l+r)/2];    int a = l; int b = r;    while (a <= b)      while (xs[a] < pivot) { a = a + 1; }      while (xs[b] > pivot) { b = b – 1; }      if (a <= b) {        swap(xs, a, b);        a = a + 1;        b = b – 1;      }    }    if (l < b) sort(xs, l, b);    if (b < r) sort(xs, a, r);  }  void swap(int[] arr, int i, int j) {    int t = arr[i]; arr[i] = arr[j]; arr[j] = t;  }

不必深入太多的細節,就可以了解 while 循環的用法,它是通過數組中的各種元素進行迭代的,先找到一個支點,然后依次對每個子元素進行排序。毫不令人奇怪的是,while 循環也需要一組可變本地變量,在這里,這些變量被命名為 a 和 b,其中存儲的是當前支點。注意,此版本甚至可以在循環自身中使用遞歸,兩次調用循環本身,一次用于對列表左手邊的內容進行排序,另一次對列表右手邊的內容進行排序。

這足以說明清單 5 中的 quicksort 真的不太容易讀取,更不用說理解它。現在來考慮一下 Scala 中的直接 等同物(這意味著該版本與上述版本盡量接近):

清單 6. Quicksort(Scala 版)

//This is Scala  def sort(xs: Array[Int]) {    def swap(i: Int, j: Int) {      val t = xs(i); xs(i) = xs(j); xs(j) = t    }    def sort1(l: Int, r: Int) {      val pivot = xs((l + r) / 2)      var i = l; var j = r      while (i <= j) {        while (xs(i) < pivot) i += 1       while (xs(j) > pivot) j -= 1       if (i <= j) {   swap(i, j)   i += 1  j -= 1       }      }      if (l < j) sort1(l, j)      if (j < r) sort1(i, r)    }    sort1(0, xs.length 1)  }

清單 6 中的代碼看起來非常接近于 Java 版。也就是說,該代碼很長,很難看,并且難以理解(特別是并發性那一部分),明顯不具備 Java 版的一些優點。

所以,我將其改進……

清單 7. Quicksort(更好的 Scala 版)

//This is Scala  def sort(xs: Array[Int]): Array[Int] =    if (xs.length <= 1) xs    else {      val pivot = xs(xs.length / 2)      Array.concat(        sort(xs filter (pivot >)),             xs filter (pivot ==),        sort(xs filter (pivot <)))    }

顯然,清單 7 中的 Scala 代碼更簡單一些。注意遞歸的使用,避免完全 while 循環。可以對 Array 類型使用 filter 函數,從而對其中的每個元素應用 “greater-than”、“equals” 和 “less-than” 函數。事實上,在引導裝入程序之后,因為 if 表達式是返回某個值的表達式,所以從 sort() 返回的是 sort() 的定義中的(單個)表達式。

簡言之,我已經將 while 循環的可變狀態完全再次分解為傳遞給各種 sort() 調用的參數 —— 許多 Scala 狂熱愛好者認為這是編寫 Scala 代碼的正確方式。

可能值得一提的是,Scala 本身并不介意您是否使用 while 代替迭代 —— 您會看到來自編譯器的 “您在干什么,在做蠢事嗎?” 的警告。Scala 也不會阻止您在可變狀態下編寫代碼。但是,使用 while 或可變狀態意味著犧牲 Scala 語言的另一個關鍵方面,即鼓勵編寫具有良好并行性的代碼。只要有可能并且可行,“Scala 式作風” 會建議您優先在命令塊上執行遞歸。

編寫自己的語言結構

我想走捷徑來討論一下 Scala 的控制結構,做一些大多數 Java 開發人員根本無法相信的事 —— 創建自己的語言結構。

那些通過死讀書學習語言的書呆子會發現一件有趣的事:while 循環(Scala 中的一個原語結構)可能只是一個預定義函數。Scala 文檔以及假設的 “While” 定義中對此進行了解釋說明:

// This is Scala  def While (p: => Boolean) (s: => Unit) {    if (p) { s ; While(p)(s) }  }

上述語句指定了一個表達式,該表達式產生了一個布爾值和一個不返回任何結果的代碼塊(Unit),這正是 while 所期望的。

擴展這些代碼行很容易,并且可以根據需要使用它們,只需導入正確的庫即可。正如前面提到的,這是構建語言的綜合方法。在下一節介紹 try 結構的時候,請將這一點牢記于心。

再三嘗試

try 結構允許編寫如下所示代碼:

清單 8. 如果最初沒有獲得成功……

// This is Scala  val url =    try {      new URL(possibleURL)    }    catch {      case ex: MalformedURLException =>        new URL("www.tedneward.com")    }

清單 8 中的代碼與 清單 2 或 清單 3 中 if 示例中的代碼相差甚遠。實際上,它比使用傳統 Java 代碼編寫更具技巧,特別是在您想捕獲不可變位置上存儲的值的時候(正如我在 清單 4 中最后一個示例中所做的那樣)。這是 Scala 的函數特性的又一個優點!

清單 8 中所示的 case ex: 語法是另一個 Scala 結構(匹配表達式)的一部分,該表達式用于 Scala 中的模式匹配。我們將研究模式匹配,這是函數語言的一個常見特性,稍后將介紹它;現在,只把它看作一個將用于 switch/case 的概念,那么哪種 C 風格的 struct 將用于類呢?

現在,再來考慮一下異常處理。眾所周知,Scala 支持異常處理是因為它是一個表達式,但開發人員想要的是處理異常的標準方法,并不僅僅是捕獲異常的能力。在 AspectJ 中,是通過創建方面(aspect)來實現這一點的,這些方面圍繞代碼部分進行聯系,它們是通過切入點定義的,如果想讓數據庫的不同部分針對不同種類異常采取不同行為,那么必須小心編寫這些切入點 —— SQLExceptions 的處理應該不同于 IOExceptions 的處理,依此類推。

在 Scala 中,這只是微不足道的細節。請留神觀察!

清單 9. 一個自定義異常表達式

// This is Scala  object Application  {    def generateException()    {      System.out.println("Generating exception...");      throw new Exception("Generated exception");    }     def main(args : Array[String])    {      tryWithLogging  // This is not part of the language      {        generateException      }      System.out.println("Exiting main()");    }     def tryWithLogging (s: => _) {      try {        s      }      catch {        case ex: Exception =>          // where would you like to log this?   // I choose the console window, for now   ex.printStackTrace()      }    }  }

與前面討論過的 While 結構類似,tryWithLogging 代碼只是來自某個庫的函數調用(在這里,是來自同一個類)。可以在適當的地方使用不同的主題變量,不必編寫復雜的切入點代碼。

此方法的優點在于它利用了 Scala 的捕獲一級結構中橫切邏輯的功能 —— 以前只有面向方面的人才能對此進行聲明。清單 9 中的一級結構捕獲了一些異常(經過檢查的和未經檢查的都包括)并以特定方式進行處理。上述想法的副作用非常多,惟一的限制也許就是想象力了。您只需記得 Scala 像許多函數語言一樣允許使用代碼塊(aka 函數)作為參數并根據需要使用它們即可。

"for" 生成語言

所有這些都引導我們來到了 Scala 控制結構套件的實際動力源泉:for 結構。該結構看起來像是 Java 的增強 for 循環的簡單早期版,但它遠比一般的 Java 編程人員開始設想的更強大。

讓我們來看一下 Scala 如何處理集合上的簡單順序迭代,根據您的 Java 編程經驗,我想您應該非常清楚該怎么做:

清單 10. 對一個對象使用 for 循環和對所有對象使用 for 循環

// This is Scala  object Application  {    def main(args : Array[String])    {      for (i <- 1 to 10) // the left-arrow means "assignment" in Scala        System.out.println("Counting " + i)    }  }

此代碼所做的正如您期望的那樣,循環 10 次,并且每次都輸出一些值。需要小心的是:表達式 “1 to 10” 并不意味著 Scala 內置了整數感知(awareness of integer)以及從 1 到 10 的計數方式。從技術上說,這里存在一些更微妙的地方:編譯器使用 Int 類型上定義的方法 to 生成一個 Range 對象(Scala 中的任何東西都是對象,還記得嗎?),該對象包含要迭代的元素。如果用 Scala 編譯器可以看見的方式重新編寫上述代碼,那么該代碼看起來很可能如下所示:

清單 11. 編譯器看見的內容

// This is Scala  object Application  {    def main(args : Array[String])    {      for (i <- 1.to(10)) // the left-arrow means "assignment" in Scala        System.out.println("Counting " + i)    }  }

實際上,Scala 的 for 并不了解那些成員,并且并不比其他任何對象類型做得更好。它所了解的是 scala.Iterable,scala.Iterable 定義了在集合上進行迭代的基本行為。提供 Iterable 功能(從技術上說,它是 Scala 中的一個特征,但現在將它視為一個接口)的任何東西都可以用作 for 表達式的核心。List、Array,甚至是您自己的自定義類型,都可以在 for 中使用。

讓 Scala 與英語更接近

您可能已經注意到,理解清單 11 中的 Scala 的 for 循環版本更容易一些。這要感謝 Range 對象暗中將兩端都包含在內,以下英語語言語法比 Java 語言更接近些。假如有一條 Range 語句說 “from 1 to 10, do this”,那么這意味著不再產生意外的 off-by-one 錯誤。

特殊性

正如上面已經證明的那樣,for 循環可以做許多事情,并不只是遍歷可迭代的項列表。事實上,可以使用一個 for 循環在操作過程中過濾許多項,并在每個階段都產生一個新列表:

清單 12. 看一看還有哪些優點

// This is Scala  object Application  {    def main(args : Array[String])    {      for (i <- 1 to 10; i % 2 == 0)        System.out.println("Counting " + i)    }  }

注意到清單 12 中 for 表達式的第二個子句了嗎?它是一個過濾器,實際上,只有那些傳遞給過濾器(即計算 true)的元素 “向前傳給” 了循環主體。在這里,只輸出了 1 到 10 的偶數數字。

并不要求 for 表達式的各個階段都成為過濾器。您甚至可以將一些完全平淡無奇的東西(從循環本身的觀點來看)放入管道中。例如以下代碼顯示了在下一個階段進行計算之前的 i 的當前值:

清單 13. 讓我如何愛上您呢?別那么冗長

// This is Scala  object App  {    def log(item : _) : Boolean =    {      System.out.println("Evaluating " + item)      true   }     def main(args : Array[String]) =    {      for (val i <- 1 to 10; log(i); (i % 2) == 0)        System.out.println("Counting " + i)    }  }

在運行的時候,范圍 1 到 10 中的每個項都將發送給 log,它將通過顯式計算每個項是否為 true 來 “批準” 每個項。然后,for 的第三個子句將對這些項進行篩選,過濾出那些滿足是偶數的條件的元素。因此,只將偶數傳遞給了循環主體本身。

簡單性

在 Scala 中,可以將 Java 代碼中復雜的一長串語句縮短為一個簡單的表達式。例如,以下是遍歷目錄查找所有 .scala 文件并顯示每個文件名稱的方法:

清單 14. Finding .scala

// This is Scala  object App  {    def main(args : Array[String]) =    {      val filesHere = (new java.io.File(".")).listFiles      for (        file <- filesHere;        if file.isFile;        if file.getName.endsWith(".scala")      ) System.out.println("Found " + file)    }  }

這種 for 過濾很常見(并且在此上下文中,分號很讓人討厭),使用這種過濾是為了幫助您做出忽略分號的決定。此外,Scala 允許將上述示例中的圓括號之間的語句直接作為代碼塊對待:

清單 15. Finding .scala(版本 2)

// This is Scala  object App  {    def main(args : Array[String]) =    {      val filesHere = (new java.io.File(".")).listFiles      for {        file <- filesHere        if file.isFile        if file.getName.endsWith(".scala")      } System.out.println("Found " + file)    }  }

作為 Java 開發人員,您可能發現最初的圓括號加分號的語法更直觀一些,沒有分號的曲線括號語法很難讀懂。幸運的是,這兩種句法產生的代碼是等效的。

一些有趣的事

在 for 表達式的子句中可以分配一個以上的項,如清單 16 中所示。

清單 16. 名稱中有什么?

// This is Scala  object App  {    def main(args : Array[String]) =    {      // Note the array-initialization syntax; the type (Array[String])      // is inferred from the initialized elements      val names = Array("Ted Neward", "Neal Ford", "Scott Davis",        "Venkat Subramaniam", "David Geary")       for {        name <- names        firstName = name.substring(0, name.indexOf(' '))      } System.out.println("Found " + firstName)    }  }

這被稱為 “中途賦值(midstream assignment)”,其工作原理如下:定義了一個新值 firstName,該值用于保存每次執行循環后的 substring 調用的值,以后可以在循環主體中使用此值。

這還引出了嵌套 迭代的概念,所有迭代都位于同一表達式中:

清單 17. Scala grep

// This is Scala  object App  {    def grep(pattern : String, dir : java.io.File) =    {      val filesHere = dir.listFiles      for (        file <- filesHere;        if (file.getName.endsWith(".scala") || file.getName.endsWith(".java"));        line <- scala.io.Source.fromFile(file).getLines;        if line.trim.matches(pattern)      ) println(line)    }     def main(args : Array[String]) =    {      val pattern = ".*object.*"           grep pattern new java.io.File(".")    }  }

在此示例中,grep 內部的 for 使用了兩個嵌套迭代,一個在指定目錄(其中每個文件都與 file 連接在一起)中找到的所有文件上進行迭代,另一個迭代在目前正被迭代的文件(與 line 本地變量連接在一起)中發現的所有行上進行迭代。

使用 Scala 的 for 結構可以做更多的事,但目前為止提供的示例已足以表達我的觀點:Scala 的 for 實際上是一條管道,它在將元素傳遞給循環主體之前處理元素組成的集合,每次一個。此管道其中的一部分負責將更多的元素添加到管道中(生成器),一部分負責編輯管道中的元素(過濾器),還有一些負責處理中間的操作(比如記錄)。無論如何,Scala 會帶給您與 Java 5 中引入的 “增強的 for 循環” 不同的體驗。

匹配

今天要了解的最后一個 Scala 控制結構是 match,它提供了許多 Scala 模式匹配功能。幸運的是,模式匹配會聲明對某個值進行計算的代碼塊。首先,將執行代碼塊中最接近的匹配結果。因此,在 Scala 中可以包含以下代碼:

清單 18. 一個簡單的匹配

// This is Scala  object App  {    def main(args : Array[String]) =    {      for (arg <- args)        arg match {   case "Java" => println("Java is nice...")   case "Scala" => println("Scala is cool...")   case "Ruby" => println("Ruby is for wimps...")   case _ => println("What are you, a VB programmer?")        }    }  }

剛開始您可能將 Scala 模式匹配設想為支持 String 的 “開關’,帶有通常用作通配符的下劃線字符,而這正是典型開關中的默認情況。但是,這樣想會極大地低估該語言。模式匹配是許多(但不是大多數)函數語言中可以找到的另一個特性,它提供了一些有用的功能。

對于初學者(盡管這沒什么好奇怪的),可能認為 match 表達式自身會產生一個值,該值可能出現在賦值語句的右邊,正如 if 和 try 語句所做的那樣。這一點本身也很有用,但匹配的真正威力體現在基于各種類型進行匹配時,而不是如上所述匹配單個類型的值,或者更多的時候,它是兩種匹配的組合。

因此,假設您有一個聲明返回 Object 的函數或方法 —— 在這里,Java 的 java.lang.reflect.Method.invoke() 方法的結果可能是一個好例子。通常,在使用 Java 語言計算結果時,首先應該確定其類型;但在 Scala 中,可以使用模式匹配簡化該操作:

清單 19. 您是什么?

//This is Scala  object App  {    def main(args : Array[String]) =    {      // The Any type is exactly what it sounds like: a kind of wildcard that      // accepts any type      def describe(x: Any) = x match {         case 5 => "five"         case true => "truth"         case "hello" => "hi!"         case Nil => "the empty list"         case _ => "something else"       }            println describe(5)      println describe("hello")    }  }

因為 match 的很容易簡單明了地描述如何針對各種值和類型進行匹配的能力,模式匹配常用于解析器和解釋器中,在那里,解析流中的當前標記是與一系列可能的匹配子句匹配的。然后,將針對另一系列子句應用下一個標記,依此類推(注意,這也是使用函數語言編寫許多語言解析器、編譯器和其他與代碼有關的工具的部分原因,這些函數語言中包括 Haskell 或 ML)。

關于模式匹配,還有許多可說的東西,但這些會將我們直接引導至 Scala 的另一個特性 case 類,我想將它留到下次再介紹。

Scala 在許多方面看起來都非常類似于 Java,但實際上只有 for 結構存在一些相似性。核心語法元素的函數特性不僅提供了一些有用的特性(比如已經提到的賦值功能),還提供了使用新穎有趣的方式擴展語言的能力,不必修改核心 javac 編譯器本身。這使該語言更加符合 DSL 的定義(這些 DSL 是在現有語言的語法中定義的),并且更加符合編程人員根據一組核心原語(a la Lisp 或 Scheme)構建抽象的愿望。

以上就是Scala控制結構指的是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

疏附县| 高密市| 朝阳区| 中方县| 基隆市| 民乐县| 金门县| 阿拉善左旗| 铅山县| 温宿县| 土默特右旗| 图木舒克市| 东源县| 永丰县| 开江县| 辽中县| 大冶市| 南充市| 嘉善县| 公安县| 永州市| 封丘县| 宁陵县| 嘉定区| 开化县| 荥阳市| 巴彦淖尔市| 罗源县| 阜城县| 兴仁县| 南川市| 吉水县| 宁河县| 封开县| 长治市| 凤冈县| 蕲春县| 临沭县| 宁南县| 静安区| 长寿区|