雜記四:scala 柯理化和隱式轉換
1、柯理化
柯里化(Currying)指的是將原來接受兩個引數的函式變成新的接受一個引數的函式的過程。新的函式返回一個以原有第二個引數為引數的函式。
例項
首先我們定義一個函式:
def add(x:Int,y:Int)=x+y
那麼我們應用的時候,應該是這樣用:add(1,2)
現在我們把這個函式變一下形:
def add(x:Int)(y:Int) = x + y
那麼我們應用的時候,應該是這樣用:add(1)(2),最後結果都一樣是3,這種方式(過程)就叫柯里化。
實現過程
add(1)(2) 實際上是依次呼叫兩個普通函式(非柯里化函式),第一次呼叫使用一個引數 x,返回一個函式型別的值,第二次使用引數y呼叫這個函式型別的值。
實質上最先演變成這樣一個方法:
def add(x:Int)=(y:Int)=>x+y
那麼這個函式是什麼意思呢? 接收一個x為引數,返回一個匿名函式,該匿名函式的定義是:接收一個Int型引數y,函式體為x+y。現在我們來對這個方法進行呼叫。
val result = add(1)
返回一個result,那result的值應該是一個匿名函式:(y:Int)=>1+y
所以為了得到結果,我們繼續呼叫result。
val sum = result(2)
最後列印出來的結果就是3。
完整例項
下面是一個完整例項:
object Test {
def main(args: Array[String]) {
val str1:String = "Hello, "
val str2:String = "Scala!"
println( "str1 + str2 = " + strcat(str1)(str2) )
}
def strcat(s1: String)(s2: String) = {
s1 + s2
}
}
執行以上程式碼,輸出結果為:
$ scalac Test.scala
$ scala Test
str1 + str2 = Hello, Scala!
2、隱式轉換
我們需要某個類中的一個方法,但是這個類沒有提供這樣的一個方法,所以我們需要隱式轉換,轉換成提供了這個方法的類,然後再呼叫這個方法。
定義在公共物件中的隱式轉換:
import scala.io.Source
import java.io.File
//這裡的RichFile相當於File的增強類 需要將被增強的類作為引數傳入構造器中
class RichFile(val file: File) {
def read = {
Source.fromFile(file.getPath).mkString
}
}
//implicit是隱式轉換的關鍵字 這裡定義一個隱式轉換函式把當前型別轉換成增強的型別(函式名稱一般是source2target)
object Context {
//File --> RichFile
implicit def file2RichFile(file: File) = new RichFile(file)
}
object Hello_Implicit_Conversions {
def main(args: Array[String]): Unit = {
//匯入隱式轉換
import Context.file2RichFile
//File類本身沒有read方法 通過隱式轉換完成
//這裡的read方法是RichFile類中的方法 需要通過隱式轉換File --> RichFile
println(new File("E:\\projectTest\\1.txt").read)
}
}
定義在原型別的伴生物件中:
class Person(val name: String)
// 在伴生物件中定義隱式轉換函式
object Person{
implicit def person2Thor(p: Person): Thor = new Thor(p.name)
}
class Thor(val name: String) {
def hammer(): Unit = {
println(name + "舉起雷神之錘")
}
}
// 使用示例
object ScalaApp extends App {
new Person("普通人").hammer()
}
隱式引數
object Context_Implicits {
implicit val default: String = "Java"
}
object Param {
//函式中用implicit關鍵字 定義隱式引數
def print(context: String)(implicit language: String){
println(language+":"+context)
}
}
object Implicit_Parameters {
def main(args: Array[String]): Unit = {
//隱式引數正常是可以傳值的,和普通函式傳值一樣 但是也可以不傳值,因為有預設值(預設配置)
Param.print("Spark")("Scala") //Scala:Spark
import Context_Implicits._
//隱式引數沒有傳值,編譯器會在全域性範圍內搜尋 有沒有implicit String型別的隱式值 並傳入
Param.print("Hadoop") //Java:Hadoop
}
}
相關文章
- Scala - 隱式轉換和隱式引數
- Scala Essentials: 隱式轉換
- Scala隱式轉換與隱式引數
- Cris 的 Scala 筆記整理(十):隱式轉換筆記
- scala中隱式轉換之隱式轉換呼叫類中本不存在的方法
- scala隱式轉換優先順序問題
- js顯式轉換和隱式轉換JS
- 好程式設計師大資料教程Scala系列之隱式轉換和隱式引數程式設計師大資料
- 學好Spark/Kafka必須要掌握的Scala技術點(三)高階函式、方法、柯里化、隱式轉換SparkKafka函式
- Solidity語言學習筆記————11、隱式轉換和顯式轉換Solid筆記
- 筆記:隱式轉換規則筆記
- Java資料型別的顯式轉換和隱式轉換Java資料型別
- javascript 隱式轉換JavaScript
- sql隱式轉換SQL
- Oracle 隱式轉換Oracle
- java隱式轉換Java
- MySQL和Oracle中的隱式轉換MySqlOracle
- 【隱式轉換】注意隱式轉換將導致索引無法使用索引
- scala簡明教程:偏函式、高階函式、Future非同步程式設計、隱式轉換函式非同步程式設計
- JavaScript隱式型別轉換JavaScript型別
- mysql隱式轉換問題MySql
- MySQL 隱式型別轉換MySql型別
- 【C++】禁止隱式轉換C++
- javascript資料型別隱式和顯式轉換詳解JavaScript資料型別
- scala和java資料型別轉換Java資料型別
- [] == ![],走進==隱式轉換的世界
- MySQL索引失效之隱式轉換MySql索引
- JS隱式轉換--寬鬆相等(==)JS
- Scala的ACM轉換ACM
- 從Java的型別轉換看MySQL和Oracle中的隱式轉換(二)Java型別MySqlOracle
- Scala隱式轉換理論及進階實踐-Coding技術進階實戰
- C# 隱式型別轉換(轉載)C#型別
- oracle內部轉換函式雜談Oracle函式
- oracle資料隱式轉換規則Oracle
- JavaScript 隱式資料型別轉換JavaScript資料型別
- Spark中的三種隱式轉換Spark
- 如何實現隱式型別轉換型別
- 你所忽略的js隱式轉換JS