在GitHub上編輯此頁面

隱式轉換

隱式轉換由scala.Conversion類別的已給予實例定義。此類別定義在套件scala中,如下所示

abstract class Conversion[-T, +U] extends (T => U):
  def apply (x: T): U

例如,以下是從字串Token的隱式轉換

given Conversion[String, Token] with
  def apply(str: String): Token = new KeyWord(str)

使用別名,可以更簡潔地表示為

given Conversion[String, Token] = new KeyWord(_)

隱式轉換會在三種情況下由編譯器自動套用

  1. 如果運算式e具有類型T,而T不符合運算式的預期類型S
  2. 在選擇e.m中,e的類型為T,但T未定義成員m
  3. 在應用程式 e.m(args) 中,若 eT 型別,則 T 定義一些名為 m 的成員,但這些成員都不能套用至參數 args

在第一個情況中,編譯器會尋找一個給定的 scala.Conversion 執行個體,將 T 型別的參數對應至 S 型別。在第二和第三個情況中,它會尋找一個給定的 scala.Conversion 執行個體,將 T 型別的參數對應至定義成員 m 的型別,如果存在,則可以套用至 args。如果找到此類執行個體 C,則會以 C.apply(e) 取代表達式 e

範例

  1. Predef 套件包含「自動封裝」轉換,將原始數字型別對應至 java.lang.Number 的子類別。例如,從 Intjava.lang.Integer 的轉換可以定義如下

    given int2Integer: Conversion[Int, java.lang.Integer] =
      java.lang.Integer.valueOf(_)
    
  2. 「磁鐵」模式有時用於表達方法的許多變體。與定義方法的重載版本不同,也可以讓方法採用一個或多個特別定義的「磁鐵」型別的參數,其中可以轉換各種參數型別。範例

    object Completions:
    
      // The argument "magnet" type
      enum CompletionArg:
        case Error(s: String)
        case Response(f: Future[HttpResponse])
        case Status(code: Future[StatusCode])
    
      object CompletionArg:
    
        // conversions defining the possible arguments to pass to `complete`
        // these always come with CompletionArg
        // They can be invoked explicitly, e.g.
        //
        //   CompletionArg.fromStatusCode(statusCode)
    
        given fromString    : Conversion[String, CompletionArg]               = Error(_)
        given fromFuture    : Conversion[Future[HttpResponse], CompletionArg] = Response(_)
        given fromStatusCode: Conversion[Future[StatusCode], CompletionArg]   = Status(_)
      end CompletionArg
      import CompletionArg.*
    
      def complete[T](arg: CompletionArg) = arg match
        case Error(s) => ...
        case Response(f) => ...
        case Status(code) => ...
    
    end Completions
    

此設定比 complete 的簡單重載更複雜,但如果無法使用一般重載(如上述情況,因為我們無法使用兩個採用 Future[...] 參數的重載方法),或者如果一般重載會導致變體的組合爆炸,則此設定仍然有用。

在本文中