Scala--高階函數

来源:http://www.cnblogs.com/one--way/archive/2016/09/02/5833930.html
-Advertisement-
Play Games

一、作為值的函數 結果: 二、匿名函數 三、帶函數參數的函數 結果: 四、參數(類型)推斷 匿名函數簡寫: 五、一些有用的高階函數 map這個方法將一個函數應用到某個集合的所有元素並返回結果 foreach將函數應用到每個元素,並不返回結果 結果: filter輸出所有匹配某個特定條件的元素 結果: ...


一、作為值的函數

  import scala.math._

  val num  = 3.14
  val func = ceil _ // _意味著確實指的是這個函數,而不是忘記了傳參數 ,func是一個函數變數,內容保存的是個函數

  val v = func(num)
  println(v)
  val arr = Array(1.0,3.14,4).map(func)  //將函數func傳遞給map方法,將他應用到數組中的所有值,然後返回結果數組
  for(i<- arr) print(i+" ")

結果:

4.0
1.0 4.0 4.0 

 

二、匿名函數

  val func = (x:Double) => x*3 //匿名函數
 val arr1 = Array(2.0,4,6).map((x:Double)=> x*3) //匿名函數 val arr2 = Array(2.0,4,6).map{(x:Double)=> x*3} //匿名函數,可以將函數用{}括起來 val arr3 = Array(2.0,4,6) map{(x:Double)=> x*3} //匿名函數,中置表示法,可以不用句號 for(i <- arr1) print(i+" ")

 

三、帶函數參數的函數

  import scala.math._
  def valueAtFunc(f: (Double) => Double) = { // f: (Double) => Double 定義函數參數為 double,返回值為double
    f(0.25) //調用函數的參數為 2.0
  }

  println(valueAtFunc(ceil _))  //將函數傳遞個 函數valueAtFunc
  println(valueAtFunc(sqrt _))

結果:

1.0
0.5

 

四、參數(類型)推斷

  import scala.math._
    def valueAtFunc(f: (Double) => Double) = { // f: (Double) => Double 定義函數參數為 double,返回值為double
      f(0.25) //調用函數的參數為 2.0
    }

    println(valueAtFunc(ceil _))  //將函數傳遞個 函數valueAtFunc
    println(valueAtFunc(sqrt _))

  valueAtFunc((x:Double) => x*3 ) //匿名函數,指定類型
  valueAtFunc((x)=>x*3)      //匿名函數,已知參數類型
  valueAtFunc(x=>x*3)        //匿名函數,已知參數類型,去掉括弧
  valueAtFunc(_*3)           //使用_替換 x

  val f1 = 3 * _   //錯誤,沒指定類型
  val f2 = 3 *(_:Double)  //ok
  val f3:(Double)=>Double = 3 * _ // ok 指定了f3類型

匿名函數簡寫:

valueAtFunc((x:Double) => x*3 ) //匿名函數,指定類型
valueAtFunc((x)=>x*3) //匿名函數,已知參數類型
valueAtFunc(x=>x*3) //匿名函數,已知參數類型,去掉括弧
valueAtFunc(_*3) //使用_替換 x

 

五、一些有用的高階函數

map這個方法將一個函數應用到某個集合的所有元素並返回結果

foreach將函數應用到每個元素,並不返回結果

(0 to 9).map("*" * _).foreach(println(_))

結果:

*
**
***
****
*****
******
*******
********
*********

filter輸出所有匹配某個特定條件的元素

(0 to 9).filter(_ % 2 == 0).foreach(println(_))

結果:

0
2
4
6
8

reduceLeft方法接收一個二元函數,從左到右遍歷元素

println((0 to 9).reduceLeft(_ + _))   // 相當於  (...((((0+1) + 2) + 3) + 4) ...+ 9)

結果

45

sortWith方法二元排序

"I am a bad guy".split(" ").sortWith(_.length<_.length).foreach(println(_))

結果:

I
a
am
bad
guy

 

六、閉包

閉包由代碼和代碼用到的非局部變數定義構成

 

七、SAM轉換

Single Abstract Method

 

 

八、柯里化

Currying,指的是將原本接收兩個參數的函數變成新的接收一個參數的函數的過程。

  def mul(x:Int, y:Int) = x * y  //接收兩個參數的函數

  def mulOneAtATime(x:Int) = (y:Int)=> x * y  //接收一個參數的函數,需要接收兩次參數
  def mulOneAtATime1(x:Int)(y:Int) = x * y //柯里化 簡寫
  println(mulOneAtATime(3)(4))
  println(mulOneAtATime1(3)(4))

 

柯里化用途:

傳遞一個參數調用函數,有助於對參數類型進行推斷,即類型推斷

  val a = Array("Hello","World")
  val b = Array("hello","world")

  a.corresponds(b)(_.equalsIgnoreCase(_))

Scaladoc說明

that是String類型的序列,所以第二個函數參數是(String, String) => Boolean,所以適用函數_.equalsIgnoreCase(_)傳遞兩個String類型參數的函數。

 

九、控制抽象

實現類似while條件控制,柯里化實現

  //until函數  類似於while
  def until(condition: => Boolean) (block: => Unit) { //不帶參數,沒有返回值的函數 block: => Unit
    if(condition){
      block
      until(condition)(block)
    }
  }

  var x:Int = 10
  until(x > 0){ //傳遞兩個函數體, 第一個函數體當做條件,第二個函數體當做計算塊
    x -= 1
    println(x)
  }

結果:

9
8
7
6
5
4
3
2
1
0

 

十、return表達式

  //until函數  類似於while
  def until(condition: => Boolean) (block: => Unit) { //不帶參數,沒有返回值的函數 block: => Unit
    if(condition){
      block
      until(condition)(block)
    }
  }

  var x:Int = 10
  until(x > 0){ //傳遞兩個函數體, 第一個函數體當做條件,第二個函數體當做計算塊
    x -= 1
    println(x)
  }

  def indexOf(str: String, ch:Char): Int ={
    var i = 0
    until( i!=str.length){
      if( str(i) == ch) return i      //return 返回給帶名函數,並不返回給匿名函數 {if(str(i) == ch) return i; i+=1}的until
      i+=1
    }
    return -1
  }
  println(indexOf("Hello", 'i'))

return在控制抽象中很有用。

 

 

參考《快學Scala》

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實習就要結束了,最終要上交的是網上書城項目和一份文檔。接下來簡要介紹一下項目。 項目是根據三層架構來寫,數據訪問層(DAO層)、系統業務邏輯控制處理層(servlet層)、和界面層(jsp)。 首先在DAO層構造好SQL語句,對資料庫進行操作,在servlet層調用Dao層相關方法進行相應的邏輯處理 ...
  • java中獲取網頁的get或post數據的方法有以下三種: getParameter(name); 獲取單參數的方法。 getParameterValues(name); 獲取多參數值的方法,如覆選框的值,返回一個數組 getParameterNames(name); 獲取request中的所有參數 ...
  • RT,you get 是一個視頻離線下載工具, https://github.com/soimort/you get 另一個同類工具 youtube dl 也是python 實現,雖然名為 youtube dl 但是從文檔上看,支持很多網站 https://github.com/rg3/youtub ...
  • 最近由於要做一個爬蟲項目,要對很多網站進行爬取,所以一直都在看這方面的文章。在翻閱了很多資料後,下載了一個curl庫,著實對項目有了很大的幫助。 一、LibCurl基本編程框架libcurl是一個跨平臺的網路協議庫,支持http, https, ftp, gopher, telnet, dict, ...
  • 一.為什麼要進行數據校驗 對於一個web應用而言,所有的應用數據都是通過瀏覽器收集的,用戶的輸入信息是非常複雜的,對於一些用戶操作不熟練,輸入出錯,等網路傳輸不穩定,這些都有可能導致異常輸入。 異常的輸入,輕則導致系統非正常中斷,重則導致系統崩潰,應用程式必須能正常處理表現層接收的異常數據,通常的做 ...
  • 一.與Servlet API解耦的訪問方式 1.為了避免與Servlet API耦合在一起,方便Action類做單元測試, Struts2對HttpServletRequest、HttpSession和ServletContext進行了封裝, 構造了三個Map對象來替代這三種對象,在Action中, ...
  • 由於在數據表之間可以通過外鍵進行關聯,在使用Hibernate操作映射到存在關聯關係的數據表的對象時,需要將對象的關聯關係與數據表的外鍵關聯進行映射。 1.前言 這篇文章標題為單向多對一,其實是為以後的種種映射和HQL操作作一個鋪墊,實現單向多對一或者一對多再或者雙向多對一都很簡單,畢竟現在的工具實 ...
  • openopen(url)- 在瀏覽器中打開URL,可以接受相對和絕對路徑兩種形式type type(inputLocator, value)- 模擬人手的輸入過程,往指定的input中輸入值- 也適合給覆選和單選框賦值 clickclick(elementLocator)- 點擊連接,按鈕,覆選和 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...