scala中的隱式類(lèi)型轉(zhuǎn)換的實(shí)現(xiàn)
Scala語(yǔ)言中的隱式轉(zhuǎn)換是一個(gè)十分強(qiáng)大的語(yǔ)言特性,主要可以起到兩個(gè)作用:
一.自動(dòng)進(jìn)行某些數(shù)據(jù)類(lèi)型的隱式轉(zhuǎn)換
String類(lèi)型是不能自動(dòng)轉(zhuǎn)換為Int類(lèi)型的,所以當(dāng)給一個(gè)Int類(lèi)型的變量或常量賦予String類(lèi)型的值時(shí)編譯器將報(bào)錯(cuò)。所以,一下語(yǔ)句是錯(cuò)誤的。
val x: Int = "100"
如果需要將一個(gè)字符串類(lèi)型的整形數(shù)值賦給Int,比如使用String.toInt方法,例如:
val x: Int = "100".toInt
如果想讓字符串自動(dòng)轉(zhuǎn)換為整形,就可以使用隱式轉(zhuǎn)換。可以定義如下函數(shù)。
implicit def strToInt(str: String) = str.toInt
這時(shí)你再對(duì)Int類(lèi)型的變量賦值字符串時(shí),字符串就會(huì)自動(dòng)轉(zhuǎn)換為Int。
scala> val x:Int = "00" x: Int = 100
如果你此時(shí)定義一個(gè)兩數(shù)相加的函數(shù)
def add(x: Int, y: Int) = x + y
就可以達(dá)到這種效果:
scala> add("100", 200)
res1: Int = 300
隱式轉(zhuǎn)換有一定的使用規(guī)則,比較重要的有2個(gè)。
1.按照《Scala編程》這本書(shū)中所說(shuō):插入的隱式轉(zhuǎn)換必須以單一標(biāo)識(shí)符的形式處于作用域中,或與轉(zhuǎn)換的源或目標(biāo)類(lèi)型關(guān)聯(lián)在一起。Scala編譯器將僅考慮處于作用域之內(nèi)的隱式轉(zhuǎn)換。
簡(jiǎn)而言之,就是在使用隱式轉(zhuǎn)換之前,需要用import把隱式轉(zhuǎn)換引用到當(dāng)前的作用域里或者就在作用域里定義隱式轉(zhuǎn)換。除了隱式轉(zhuǎn)換被引入進(jìn)當(dāng)前作用域之外,還有一種方式可以使用隱式轉(zhuǎn)換,就是編譯器會(huì)在源類(lèi)型或者期望的伴生對(duì)象中尋找隱式定義。
2.無(wú)歧義規(guī)則:隱式轉(zhuǎn)換只能在無(wú)其他可用轉(zhuǎn)換的前提下才能操作。如果在同一作用域里,對(duì)同一源類(lèi)型定義一個(gè)以上的隱式轉(zhuǎn)換函數(shù),如果多種隱式轉(zhuǎn)換函數(shù)都可以匹配,那么編譯器將報(bào)錯(cuò),所以在使用時(shí)請(qǐng)移除不必要的隱式定義。
二.隱式參數(shù)
柯里化函數(shù)會(huì)有多個(gè)參數(shù)列表,當(dāng)希望對(duì)某個(gè)參數(shù)列表采用默認(rèn)參數(shù)時(shí),可以使用implicit提供的隱式參數(shù)功能。做法是在需要自動(dòng)填充的參數(shù)列表最開(kāi)端加上implicit,然后在定義域內(nèi)定義需要填充的默認(rèn)參數(shù)值常量,并在常量的定義之前聲明implicit。
視界
當(dāng)有如下定義時(shí)
class Container[A <% Int] { def addIt(x: A) = 123 + x }
表示A類(lèi)型必須可視為Int。簡(jiǎn)單的說(shuō),就是需要有一個(gè)轉(zhuǎn)換函數(shù),可以自動(dòng)的將A類(lèi)型,轉(zhuǎn)換為Int類(lèi)型,如果沒(méi)有這樣的轉(zhuǎn)換函數(shù),可以使用implicit定義。
寫(xiě)一個(gè)類(lèi)測(cè)試一下Scala中的隱式轉(zhuǎn)換的用法:
class Fraction(n: Int, d: Int) {
// def den = d
private val den = d;
// def num = n 類(lèi)參數(shù)定義為方法或字段都可以
private val num = n;
// 定義乘法
def *(other: Fraction) = Fraction(other.num * this.num, other.den * this.den)
// 重寫(xiě)toString
override def toString() = s"$num / $den"
}
//伴生對(duì)象
object Fraction {
// implicit隱轉(zhuǎn) 方法名無(wú)關(guān)可以隨意改,自動(dòng)調(diào)用
implicit def int2Fraction(n: Int) = Fraction(n, 1)
def apply(n: Int, d: Int) = {
new Fraction(n, d)
}
def unapply(frac: Fraction) = if (frac.den == 0) None else Some((frac.num, frac.den))
}
object TestFrac extends App{
// 3 隱式調(diào)用了int2Fraction方法被轉(zhuǎn)化為一個(gè)Fraction對(duì)象Fraction(3,1)
val result = 3 * Fraction(4,5)
// 也可以顯示調(diào)用
val result2 = Fraction.int2Fraction(5) * Fraction(3,4)
println(result)
// unapply
val Fraction(num,den) = result
println(num,den)
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
RxJava2 Scheduler使用實(shí)例深入解析
這篇文章主要為大家介紹了RxJava2 Scheduler使用實(shí)例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度
這篇文章主要介紹了淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度,想了解Ribbon灰度的同學(xué)可以參考下2021-04-04
解決springboot+shiro+thymeleaf頁(yè)面級(jí)元素的權(quán)限控制問(wèn)題
這篇文章主要介紹了解決springboot+shiro+thymeleaf頁(yè)面級(jí)元素的權(quán)限控制問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Java 如何將表格數(shù)據(jù)導(dǎo)入word文檔中
這篇文章主要介紹了Java將表格數(shù)據(jù)導(dǎo)入word文檔中的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
用java將GBK工程轉(zhuǎn)為uft8的方法實(shí)例
本篇文章主要介紹了用java將GBK工程轉(zhuǎn)為uft8的方法實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
SpringBoot依賴(lài)和代碼分開(kāi)打包的實(shí)現(xiàn)步驟
本文主要介紹了SpringBoot依賴(lài)和代碼分開(kāi)打包的實(shí)現(xiàn)步驟,,這種方法將依賴(lài)和代碼分開(kāi)打包,一般更新只有代碼修改,Pom文件是不會(huì)經(jīng)常改動(dòng)的,感興趣的可以了解一下2023-10-10
SpringCloud項(xiàng)目中集成Sentinel問(wèn)題
在SpringCloud項(xiàng)目中集成Sentinel,可以實(shí)現(xiàn)流量控制、熔斷降級(jí)等功能,提升系統(tǒng)穩(wěn)定性和可用性,集成步驟包括添加Sentinel依賴(lài)、配置控制臺(tái)地址、啟動(dòng)控制臺(tái)、配置限流熔斷規(guī)則、使用注解和集成SpringCloudGateway,這有助于處理高并發(fā)場(chǎng)景,保護(hù)服務(wù)穩(wěn)定運(yùn)行2024-10-10

