Scala語法(七) 隱式轉換

前言

本章將介紹Scala中的隱式轉換部分.


正文

我們之前在遍歷數組的時候, 使用了1 to 10的方法. 但是, Scala內卻沒有此方法, 此處使用了隱式轉換的相關知識.

我們通過implicit -v查看Scala默認導入的隱式轉換方法.

scala> : implicit -v
/* 69 implicit members imported from scala.Predef */
  /* 7 inherited from scala */
  final implicit class ArrayCharSequence extends CharSequence
  final implicit class ArrowAssoc[A] extends AnyVal
  final implicit class Ensuring[A] extends AnyVal
  final implicit class RichException extends AnyVal
  final implicit class SeqCharSequence extends CharSequence
  final implicit class StringFormat[A] extends AnyVal
  final implicit class any2stringadd[A] extends AnyVal

  /* 40 inherited from scala.Predef */
  implicit def ArrowAssoc[A](self: A): ArrowAssoc[A]
  implicit def Ensuring[A](self: A): Ensuring[A]
  implicit def StringFormat[A](self: A): StringFormat[A]
  implicit def any2stringadd[A](self: A): any2stringadd[A]

  implicit def booleanArrayOps(xs: Array[Boolean]): mutable.ArrayOps[Boolean]
  implicit def byteArrayOps(xs: Array[Byte]): mutable.ArrayOps[Byte]
  implicit def charArrayOps(xs: Array[Char]): mutable.ArrayOps[Char]
  implicit def doubleArrayOps(xs: Array[Double]): mutable.ArrayOps[Double]
  implicit def floatArrayOps(xs: Array[Float]): mutable.ArrayOps[Float]
  implicit def genericArrayOps[T](xs: Array[T]): mutable.ArrayOps[T]
  implicit def intArrayOps(xs: Array[Int]): mutable.ArrayOps[Int]
  implicit def longArrayOps(xs: Array[Long]): mutable.ArrayOps[Long]
  implicit def refArrayOps[T <: AnyRef](xs: Array[T]): mutable.ArrayOps[T]
  implicit def shortArrayOps(xs: Array[Short]): mutable.ArrayOps[Short]
  implicit def unitArrayOps(xs: Array[Unit]): mutable.ArrayOps[Unit]

  implicit def $conforms[A]: <:<[A,A]
  implicit def ArrayCharSequence(__arrayOfChars: Array[Char]): ArrayCharSequence
  implicit def Boolean2boolean(x: Boolean): Boolean
  implicit def Byte2byte(x: Byte): Byte
  implicit def Character2char(x: Character): Char
  implicit def Double2double(x: Double): Double
  implicit def Float2float(x: Float): Float
  implicit def Integer2int(x: Integer): Int
  implicit def Long2long(x: Long): Long
  implicit def RichException(self: Throwable): RichException
  implicit def SeqCharSequence(__sequenceOfChars: IndexedSeq[Char]): SeqCharSequence
  implicit def Short2short(x: Short): Short
  implicit val StringCanBuildFrom: generic.CanBuildFrom[String,Char,String]
  implicit def augmentString(x: String): immutable.StringOps
  implicit def boolean2Boolean(x: Boolean): Boolean
  implicit def byte2Byte(x: Byte): Byte
  implicit def char2Character(x: Char): Character
  implicit def double2Double(x: Double): Double
  implicit def float2Float(x: Float): Float
  implicit def int2Integer(x: Int): Integer
  implicit def long2Long(x: Long): Long
  implicit def short2Short(x: Short): Short
  implicit def tuple2ToZippedOps[T1, T2](x: (T1, T2)): runtime.Tuple2Zipped.Ops[T1,T2]
  implicit def tuple3ToZippedOps[T1, T2, T3](x: (T1, T2, T3)): runtime.Tuple3Zipped.Ops[T1,T2,T3]
  implicit def unaugmentString(x: immutable.StringOps): String

  /* 22 inherited from scala.LowPriorityImplicits */
  implicit def genericWrapArray[T](xs: Array[T]): mutable.WrappedArray[T]
  implicit def wrapBooleanArray(xs: Array[Boolean]): mutable.WrappedArray[Boolean]
  implicit def wrapByteArray(xs: Array[Byte]): mutable.WrappedArray[Byte]
  implicit def wrapCharArray(xs: Array[Char]): mutable.WrappedArray[Char]
  implicit def wrapDoubleArray(xs: Array[Double]): mutable.WrappedArray[Double]
  implicit def wrapFloatArray(xs: Array[Float]): mutable.WrappedArray[Float]
  implicit def wrapIntArray(xs: Array[Int]): mutable.WrappedArray[Int]
  implicit def wrapLongArray(xs: Array[Long]): mutable.WrappedArray[Long]
  implicit def wrapRefArray[T <: AnyRef](xs: Array[T]): mutable.WrappedArray[T]
  implicit def wrapShortArray(xs: Array[Short]): mutable.WrappedArray[Short]
  implicit def wrapUnitArray(xs: Array[Unit]): mutable.WrappedArray[Unit]

  implicit def booleanWrapper(x: Boolean): runtime.RichBoolean
  implicit def byteWrapper(x: Byte): runtime.RichByte
  implicit def charWrapper(c: Char): runtime.RichChar
  implicit def doubleWrapper(x: Double): runtime.RichDouble
  implicit def fallbackStringCanBuildFrom[T]: generic.CanBuildFrom[String,T,immutable.IndexedSeq[T]]
  implicit def floatWrapper(x: Float): runtime.RichFloat
  implicit def intWrapper(x: Int): runtime.RichInt
  implicit def longWrapper(x: Long): runtime.RichLong
  implicit def shortWrapper(x: Short): runtime.RichShort
  implicit def unwrapString(ws: immutable.WrappedString): String
  implicit def wrapString(s: String): immutable.WrappedString

其中to方法在Int類中是不存在的. Scala先通過隱式轉換將Int轉換爲RichInt. 隨後使用RichInt中的to方法.
在這裏插入圖片描述


自定義隱式轉換

個人感覺, 隱式轉換更像是一種對於編寫語言的一種增強.

  • Case 1 ImplicitValue
class ImplicitValue {
  
}

// 構建門面方法
// 所有的隱式值和隱式方法都必須放入object內
object Context{
  implicit val a = "Abel"
}

object ImplicitValue{
  def sayHi() (implicit name:String = "Sean"):Unit = {
   println(s"say Hi ! $name .") 
  }
  
  def main(args: Array[String]){
    // sayHi
//    sayHi()
    
    //
    import Context._
    sayHi()

    1 to 10
  }

}
  • Case 2 RichFile

import java.io.File
import scala.io.Source


class RichFile(val f:File) {
  
  def read() = Source.fromFile(f).mkString
  
}

object MyPredef{
  implicit def fileToRichFile(f:File) = new RichFile(f)
}

object RichFile {
  def main(args: Array[String]) {
    val file = new File("./file/words.txt")
    // 目標要求
//    val content = f.read()
    
    // 顯示增強
//    val content = new RichFile(file).read()
//    println(content)
    
    // 隱式增強
    import MyPredef._
    val content2 = file.read()
    println(content2)
  }
}

// 其次, 需要特別注意都是. 隱式轉換都函數需要放在定義前.或其他的文件內.

  • Scala初始化隱式轉換
    此處便是我們之前看到到, 將Int隱式轉換爲RichInt的方法.
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章