Scala Type Parameters 1

来源:https://www.cnblogs.com/yuanzam/archive/2019/10/08/11638643.html

類型參數 表現形式:在名稱後面以方括弧表示, 何處使用 class 中,用於定義變數、入參、返回值 函數、方法 類型邊界 上邊界 compareTo Comparable` 的子類型,即需要添加上邊界 scala class Pair[T : LowerBound` 替換第一個元素為 T 的父類 R ...


類型參數

  • 表現形式:在名稱後面以方括弧表示, Array[T]
  • 何處使用
    • class 中,用於定義變數、入參、返回值

      class Pair[T, S](val first: T, val second: S)
      // scala 可自動推斷具體的類型
      val p = new Pair(42, "String") // Pair[Int, String]
    • 函數、方法

      def getMiddle[T](a: Array[T]) = a(a.length / 2)
  • 類型邊界

    • 上邊界 T <: UpperBound

      // 比較大小
      class Pair[T](val first: T, val second: T) {
        def smaller = if (first.compareTo(second) < 0) first else second  
      }

      無法確定 first 是否存在 compareTo 方法,所以必須添加約束,fist 必須是 Comparable 的子類型,即需要添加上邊界

      class Pair[T <: Comparable[T]](val first: T, val second: T) {
        def smaller = if (first.compareTo(second) < 0) first else second
      }
    • 下邊界 T >: LowerBound

      // 替換第一個元素
      class Pair[T](val first: T, val second: T) {
        def replaceFirst(newFirst: T) = new Pair[T](newFirst, second)
      }

      替換第一個元素為 T 的父類 R,那麼返回類型是什麼? 如果需要返回 R,則需要添加約束,即需要下邊界;否則返回的類型為 Any

      // 返回類型自動推斷為 new Pair[R]
      def replaceFirst[R >: T](newFirst: R) = new Pair(newFirst, second)
    • 上下文邊界 T : ContextBound

      Scala 2.8 對 Array 進行了更新優化,使用隱式轉換和 manifest 將數組整合為 Scala 的集合庫

      def tabulate[T](len: Int, f: Int => T)(implicitm: ClassManifest[T]) = {
        val xs = new Array[T](len)
        for(i <- 0 until len) xs(i) = f(i)
        xs
      }
      
      // 簡化後
      def tabulate[T: ClassManifest](len: Int, f: Int => T) = {
        val xs = new Array[T](len)
        for(i <- 0 until len) xs(i) = f(i)
        xs
      }
      • ClassTag, 指定運行時的類型,如 Array[Int] 在運行時想指定為 int[]

        import scala.reflect._
        def makePair[T : ClassTag](first: T, second: T) = {
          val r = new Array[T](2); r(0) = first; r(1) = second; r
        }
        
        makePair(4, 9)
        
        // 實際調用
        makePair(4, 9)(classTag)
        
        // new 操作,即 ClassTag[Int] 構建原始類型數組 int[2]
        classTag.newArray
    • 多個邊界
      • 可同時添加上界和下界 T >: Lower <: Upper
      • 不可添加多個上界或多個下屆,但可實現多個 trait,
        • T <: Comparable[T] with Serializable with Cloneable
      • 可指定多個上下文邊界 T : Ordering : ClassTag
  • 類型約束
    • 測試是否相等 T =:= U
    • 測試是否為子類 T <:< U
    • 測試是否可轉換 T => U

    要添加該約束,需添加隱式參數

    // 約束類
    class Pair[T](val first: T, val second: T)(implicit ev: T <:< Comparable[T])
    
    // 約束方法調用,只有類型滿足才能調用成功,否則報錯
    class Pair[T](val first: T, val second: T) {
      def smaller(implicit ev: T <:< Ordered[T]) =
        if (first < second) first else second
    }
    
    // 便於類型推斷
    def firstLast[A, C <: Iterable[A]](it: C) = (it.head, it.last)
    // 無法推斷類型 A
    firstLast(List(1, 2, 3)) // [Nothing, List[Int]]
    // 添加約束關係
    def firstLast[A, C](it: C)(implicit ev: C <:< Iterable[A]) = (it.head, it.last)

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

更多相關文章
  • 一、概述 單例模式是設計模式中相對簡單且非常常見的一種設計模式,但是同時也是非常經典的 高頻 面試題,相信還是有很多人在面試時會掛在這裡。本篇文章主要針對單例模式做一個回顧,記錄單例模式的應用場景、常見寫法、針對線程安全進行調試(看得見的線程)以及總結。相信大家看完這篇文章之後,對單例模式有一個非常 ...
  • 原文地址: "梁桂釗的博客" 博客地址: "http://blog.720ui.com" 歡迎關註公眾號:「服務端思維」。一群同頻者,一起成長,一起精進,打破認知的局限性。 漫談 GOF 設計模式在 Spring 框架中的實現 在開始正文之前,請你先思考幾個問題: 你項目中有使用哪些 GOF 設計模 ...
  • Josephus問題,在這個古老的問題中,N個深陷絕境的人一致同意通過以下方式減少生存的人數。他們圍坐一圈(位置記為0~N-1)並從第一個人報數,報到M的人會被殺死, 知道最後一個人留下來。傳說中Josephus找到了不會被殺死的位置。 接收N和M的值,列印出被殺死的順序: ...
  • 一、IDE上繼續新建工程 1.在src目錄下新建軟體包:package機制後面再講,目前先用著 2.給package命名一個名稱:com.bjpowernode.java_learning 3.軟體包下新建一個類 4.軟體包是Java語法中的一部分,後面再講 面向對象的封裝性 二、快捷鍵 CTRL ...
  • 1. 基本類型包裝類 大家回想下,在第三篇文章中我們學習Java中的基本數據類型時,說Java中有8種基本的數據類型,可是這些數據是基本數據,想對其進行複雜操作,變的很難。怎麼辦呢? 1.1 基本類型包裝類概述 在實際程式使用中,程式界面上用戶輸入的數據都是以字元串類型進行存儲的。而程式開發中,我們 ...
  • 1. 快速入門 (1)我們從官網下載源碼 BCrypt 官網 http://www.mindrot.org/projects/jBCrypt/ (2)新建工程,將源碼類BCrypt拷貝到工程 (3)新建測試類,main方法中編寫代碼,實現對密碼的加密 String gensalt = BCrypt. ...
  • 1. 正則表達式 1.1 正則表達式的概念 正則表達式(英語:Regular Expression,在代碼中常簡寫為regex)。 正則表達式是一個字元串,使用單個字元串來描述、用來定義匹配規則,匹配一系列符合某個句法規則的字元串。在開發中,正則表達式通常被用來檢索、替換那些符合某個規則的文本。 1 ...
  • 1989,為了度過聖誕假期,Guido開始編寫Python語言編譯器。Python這個名字來自Guido的喜愛的電視連續劇《蒙蒂蟒蛇的飛行馬戲團》。他希望新的語言Python能夠滿足他在C和Shell之間創建全功能、易學、可擴展的語言的願景。 今天,世界上有將近600種編程語言,但也有20種流行語言 ...
一周排行
  • 前幾天發佈了 "抄抄《CSS 故障藝術》的動畫" 這篇文章,在這篇文章里介紹瞭如何使用Win2D繪製文字然後配合BlendEffect製作故障藝術的動畫。本來打算就這樣收手不玩這個動畫了,但後來又發現性能不符合理想。明明只是做做Resize動畫和用BlendEffect混合,為什麼性能會這麼差呢? ...
  • 控制條控制項: progressBar 不能按照你程式的進程自動變化,需認為計算,調整變化量 private void progressBar1_Click(object sender, EventArgs e) { this.progressBar1.Maximum = 100;//設置進度條最大長 ...
  • 首先創建一個asp.net core web應用程式 第二步 目前官方預置了7種模板項目供我們選擇。從中我們可以看出,既有我們熟悉的MVC、WebAPI,又新添加了Razor Page,以及結合比較流行的Angular、React前端框架的模板項目。 空項目模板 Program.cs using S ...
  • 對閉包的理解 1.對於成員變數和局部變數:成員變數就是方法外部,類的內部定義的變數;局部變數就是方法或語句塊內部定義的變數。局部變數必須初始化。 形式參數是局部變數,局部變數的數據存在於棧記憶體中。棧記憶體中的局部變數隨著方法的消失而消失。成員變數存儲在堆中的對象裡面,由垃圾回收器負責回收。 成員變數它 ...
  • Xamarin.Forms讀取並展示Android和iOS通訊錄 TerminalMACS客戶端 本文同步更新地址: https://dotnet9.com/11520.html https://terminalmacs.com/861.html 閱讀導航: 一、功能說明 二、代碼實現 三、源碼獲取 ...
  • 做下對文件複製操作相關的筆記: /// <summary> /// 文件幫助類 /// </summary> public class FileHelper { /// <summary> /// 複製一個目錄下所有文件到一個新目錄下 /// </summary> /// <param name=" ...
  • 前言 有一個東西叫做鴨子類型,所謂鴨子類型就是,只要一個東西表現得像鴨子那麼就能推出這玩意就是鴨子。 C 裡面其實也暗藏了很多類似鴨子類型的東西,但是很多開發者並不知道,因此也就沒法好好利用這些東西,那麼今天我細數一下這些藏在編譯器中的細節。 不是只有 和 才能 在 C 中編寫非同步代碼的時候,我們經 ...
  • [toc] 1.應用背景 底端設備有大量網路報文(位元組數組):心跳報文,數據採集報文,告警報文上報。需要有對應的報文結構去解析這些位元組流數據。 2.結構體解析 由此,我第一點就想到了用結構體去解析。原因有以下兩點: 2.1.結構體存在棧中 類屬於引用類型,存在堆中;結構體屬於值類型,存在棧中,在一個 ...
  • 《深入淺出 C#》 (第3版) [作者] (美) Andrew Stellman (美) Jennifer Greene[譯者] (中) 徐陽 丁小峰 等譯[出版] 中國電力出版社[版次] 2016年08月 第1版[印次] 2018年04月 第4次 印刷[定價] 148.00元 【引子】 要學習編程 ...
  • 記錄使用對象初始值設定項初始化對象。 using System; using System.Collections.Generic; namespace ConsoleApp2 { class Program { static void Main(string[] args) { // 使用構造函數 ...
x