scala不刻意區(qū)分原生類型和引用類型
scala單參數(shù)方法可以用運(yùn)算符形式調(diào)用,例如:
// 這兩種寫法等效
a.add(b)
a add b
scala沒有提供"++" 和 "--" 運(yùn)算符,可以使用:
a += 1
a -= 1
import scala開頭的包可以省略scala前綴
// 以下寫法等效
import scala.collection.mutable.Map
import collection.mutable.Map
apply方法可以直接在類名或者實(shí)例變量名后直接用小括號(hào)來調(diào)用
class Demo {
def apply(n: int): Unit = {}
}
可以這么調(diào)用
val demo = new Demo
demo(6) //相當(dāng)于demo.apply(6)
object Demo {
def apply(n: int): Unit = {}
}
可以這么調(diào)用
Demo(6)
這種寫法多用于構(gòu)建對(duì)象坝初,例如:
object Demo {
def apply(n: Int) = {
val demo = new Demo
demo.setXXX
// ...
demo
}
}
class Demo {
// ...
}
scala沒有checked exception
scala中if 和 else是一個(gè)表達(dá)式,因此可以這么使用:
val a = if (1 > 0) 1 else 0
如果這樣寫:
val a = if (1 < 0) 1
則相當(dāng)于:
val a = if (1 < 0) 1 else ()
()是一個(gè)Unit類,代表無(wú)值
{}代碼塊包含一系列表達(dá)式疾呻,代碼塊的值就是最后一個(gè)表達(dá)式的值
val s = {
val a, b = 1
a + b
}
// s == 2
代碼塊如果最后一條語(yǔ)句為賦值語(yǔ)句,則代碼塊的值為Unit写半,例如:
{
var n = 0
n += 1
}
readLine函數(shù)從控制臺(tái)讀取輸入:
val str = readLine("Please input a string")
for循環(huán):
for (i <- 0 to 10) {}
// i 從0到10岸蜗,包含0和10
for(i <- 0 until 10) {}
// i 從0到10,包含0不包含10
// 取字符串中每一個(gè)char可以使用循環(huán):
for(s <- "Hello") {}
scala for循環(huán)沒有break和continue叠蝇,如果想break可以使用:
import scala.util.control.Breaks._
breakable {
for (s <- 1 to 10) {
if (...) break
}
}
高級(jí)for循環(huán):
for (i <- 1 to 3; j <- 1 to 3) println(i *10 + j)
推導(dǎo)式中可以帶守衛(wèi):
for (i <- 1 to 3; j <- 1 to 3 if i != j) println(i *10 + j)
可以在for循環(huán)中定義變量:
for (i <- 1 to 3; from = 4 - i; j <- from to 3) println(i *10 + j)
for循環(huán)的循環(huán)體以yield開始可以構(gòu)造出一個(gè)新的集合:
val collection = for (i <- 1 to 3; from = 4 - i; j <- from to 3) yield i *10 + j
函數(shù)無(wú)需指明返回類型璃岳,但是遞歸函數(shù)必須指明
函數(shù)參數(shù)可以指定默認(rèn)值:
def add (x: int, y: int = 1) = {x + y}
add(1) // 返回2
add(1,3) // 返回4
變長(zhǎng)參數(shù):
def add (x: int, y: int*) {
// y被認(rèn)為是數(shù)組
for(i <- y) {}
}
集合轉(zhuǎn)換成變長(zhǎng)序列:
val a = 1 to 5
add(1, a: _*)
懶值:懶值介于val和def之間
val result = ... // 被定義的時(shí)候執(zhí)行
lazy val result = ... // 第一次使用的時(shí)候執(zhí)行
def result = ... // 每一次使用的時(shí)候都執(zhí)行
throw表達(dá)式的類型為Nothing。if/else中如果一個(gè)分支的類型為Nothing則表達(dá)式的類型為另一個(gè)分支的類型:
if (x >=0) {sqrt(x)} else throw new IllegalArgumentException("...") //類型為Double
異常捕獲采用的是模式匹配:
try {
...
} catch {
case _: ExceptionA => print("...")
case e: ExceptionB => e.printStackTrace()
}
定長(zhǎng)數(shù)組時(shí)Array悔捶,變長(zhǎng)數(shù)組為ArrayBuffer
定義數(shù)組:
val arr = new Array[Int](10) // 定義數(shù)組arr铃慷,長(zhǎng)度為10,類型為Int蜕该,所有值初始化為0
val stringArr = Array("Hello", "World")
val s = stringArr(0) // 值為"Hello"
ArrayBuffer運(yùn)算:
val a = new ArrayBuffer[int]()
a += 1// a為 (1)
a += (2, 3, 4, 5) // a為 (1, 2, 3, 4, 5)
a ++= Array(6, 7, 8, 9, 10) // a為(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
a.trimEnd(5) // a為 (1, 2, 3, 4, 5)
b.insert(index, 被插入元素序列)
b.remove(起始index, 移除元素個(gè)數(shù))
ArrayBuffer 轉(zhuǎn)換為 Array
arr.toArray
遍歷數(shù)組
for(i <- 0 until a.length) {} // 使用index
for(e <- a) {} // 不使用index
0 until (a.length, 2) // step為2
(0 until a.length).reverse // 逆序
數(shù)組常用方法:
- sum
- max
- sorted
- scala.util.Sorting.quickSort
- mkString
多維數(shù)組:
val a = Array.ofDim[Double](3, 4) // 3行4列
a(4)(2)
構(gòu)造Map:
val map = Map("key1" -> 1, "key2" -> 2) // 不可變map
val map = scala.collection.mutable.Map("key1" -> 1, "key2" -> 2) // 可變map
映射是對(duì)偶的集合犁柜,"key1" -> 1 構(gòu)造了一個(gè)對(duì)偶,相當(dāng)于("key1", 1)堂淡,因此map可以這樣構(gòu)造:
val map = Map(("key1", 1), ("key2", 2))
獲取map的值:
val value = map("key1")
map是否存在key:
map.contains("key")
map.getOrElse("key", 0) // key存在則返回key對(duì)應(yīng)的值赁温,否則返回0
map.get("key") // 返回Option對(duì)象,要么是Some(值)淤齐,要么是None
更新可變映射:
map("key") = 1
map += ("key3" -> 3, "key4" -> 4)
map -= "key4" // 移除key為"key4"的entry
遍歷映射:
for((key, value) <- map) {}
for((key, value) <- map) yield (value, key) // 反轉(zhuǎn)映射
map.keySet // 返回鍵的集合
map.values // 返回值的集合
元組
val tuple = (1, "Paul")
val name = tuple._1 // 返回1股囊,下標(biāo)從1開始而不是0
val (id, name) = tuple // id為1,name為Paul
val (id, _) = tuple // id 為1
patition分區(qū)操作:
"ABCdef".patition(_.isUpper) // 返回("ABC", "def")
zip操作:
val a = Array("a", "b", "c")
val b = Array(1, 2, 3)
val c = a.zip(b) // c為Array(("a", 1), ("b", 2), ("c", 3))
對(duì)偶的集合可以使用toMap轉(zhuǎn)換為map
方法的調(diào)用:
class A {
def func() = {}
}
可以使用a.func()
或者a.func
方式調(diào)用更啄,但是定義時(shí)候如果沒有給出小括號(hào)稚疹,例如:
class A {
def func = {}
}
則只能使用a.func
方式調(diào)用
如果成員變量的名字為a,則在scalar中a的getter方法名為a
,setter方法名為a_=
var
變量會(huì)自動(dòng)生成setter和getter
如果變量是private的則setter和getter都是private的
val
聲明的變量只有g(shù)etter方法
private[this]
變量沒有setter和getter方法
private
和private[this]
的區(qū)別
class Counter {
private var count = 0
def isLess(other: Counter) = count < other.count
// 雖然count是private類型變量内狗,但是other是Counter類型怪嫌,因此在 Counter內(nèi)部能夠正常訪問
// 此處counter若為private[this],Counter類只能訪問當(dāng)前對(duì)象的count變量
}
自動(dòng)生成java bean的setter和getter方法
@BeanProperty var a = 0
主構(gòu)造器:
class Student(val name: String, val age: Int)
主構(gòu)造器會(huì)執(zhí)行類定義中的所有語(yǔ)句
如果聲明構(gòu)造器參數(shù)沒有指明val或者var柳沙,則生成的字段為private[this]岩灭。若該字段未被使用則不會(huì)生成該字段。
私有化主構(gòu)造器:
class Person private (val name: String)
類型投影:
ArrayBuffer[Network#Member] // 任意Network實(shí)例中的Member對(duì)象
單例對(duì)象:
object Person {
}
```scala
main函數(shù):
```scala
object Demo {
def main(args: Array[String]) {}
}
也可以擴(kuò)展App特質(zhì):
object Demo extends App {
// main函數(shù)執(zhí)行的內(nèi)容
}
枚舉類型
object Direction extend Enumeration {
type Direction = Value
val EAST, WEST, SOUTH, NORTH = Value
}
包可以寫成嵌套格式:
package com {
package paul {
class A
}
}
scala中的包名是相對(duì)的赂鲤,如果要使用絕對(duì)包名噪径,需要以root開始
包對(duì)象:
每個(gè)包都有一個(gè)包對(duì)象,需要在父包中定義它数初,名字和子包一樣找爱。
package object people {}
引入包的全部成員:
import com.paul._
scala中import語(yǔ)句可以出現(xiàn)在任何地方,不局限于文件頂部
包選取器泡孩,用于引入包中的幾個(gè)成員:
import java.awt.{Color, Font}
import java.util.{HashMap => JavaHashMap} //使用別名
重寫方法必須使用override修飾符
isInstanceOf() // 檢查類型
asInstanceOf() // 轉(zhuǎn)換類型
如果只想測(cè)試p是不是某一個(gè)特定的類而不是其子類的話车摄,可以:
if (p.getClass == classOf[A]) {}
scala中protected字段對(duì)于同一個(gè)包的其他類而言是不可見的,只有它的子類可見仑鸥。這點(diǎn)和Java是不同的
超類構(gòu)造器:
class Person(val name: String)
class User(val name: String, val password: String) extends Person(name)
def只能重寫def
val只能重寫另一個(gè)val或不帶參數(shù)的def
var只能重寫另一個(gè)抽象的var
提前定義:
class Ant extends {
override val range = 2
} with Creature
重寫變量range會(huì)在Creature構(gòu)造函數(shù)之前執(zhí)行
scala檢查對(duì)象是否相等可以用==運(yùn)算符
讀取文件行:
import scala.io.Source
val source = Source.fromFile("myFile.txt", "UTF-8")
val lineIterator = source.getLines
for (line <- lineIterator) {}
source.close()
for (c <- source) {} // 處理單個(gè)字符
val iter = source.buffered
iter.head // peek下一個(gè)字符吮播,但不取出
從URL或者是其他源讀取數(shù)據(jù):
val source1 = Source.fromURL()
val source1 = Source.fromString("Hello World")
val source3 = Source.fromStdin()
讀取二進(jìn)制文件需要使用Java的類庫(kù)
Scala序列化:
@SerialVersionUID(42L) class Person extends Serialization
如果使用默認(rèn)的SerialVersionUID可以省略該注解
scala執(zhí)行系統(tǒng)命令:
import system.process._
"ls -al .." ! // 執(zhí)行結(jié)果被打印到標(biāo)準(zhǔn)輸出
!返回結(jié)果是被執(zhí)行程序的返回值眼俊,如果正常返回0薄料,否則顯示非0值
val result = "ls -al .." !! // 輸出結(jié)果會(huì)以字符串的形式返回
"ls -al .." #| "grep sec" ! // #| 為管道操作符
"ls -al .." #> new File("file.txt") ! // 輸出重定向到文件
"ls -al .." #>> new File("file.txt") ! // 輸出追加到文件末尾
"grep sec" #< new File("output.txt") ! // 文件內(nèi)容作為輸入
"grep sec" #< new File("output.txt") ! // URL內(nèi)容作為輸入
p #&& q // 如果p成功,執(zhí)行q
p #|| q // 如果p不成功泵琳,執(zhí)行q
正則表達(dá)式:
val regexp = """[abc]{1,3}""".r // String的r方法生成正則表達(dá)式。為了避免轉(zhuǎn)義誊役,可以使用原始字符串語(yǔ)法:"""..."""
迭代匹配值:
for (matching <- regexp.findAllIn("...")) {}
匹配值轉(zhuǎn)換為數(shù)組:
val matches = regexp.findAllIn("...").toArray
其他正則表達(dá)式方法:
findfirstIn, findPrefixOf, replaceFirstIn, replaceAllIn
正則表達(dá)式組:
val numItemPattern = """(\d+) ([A-Za-z]+)""".r
匹配組:
val numItemPattern (num, item) = "99 bottles"
匹配多個(gè)組
for (numItemPattern (num, item) <- numItemPatter.findAllIn("99 bottles, 100 kettles"))
實(shí)現(xiàn)多個(gè)特質(zhì):
class A extend B with C with D
如果特質(zhì)中方法已經(jīng)實(shí)現(xiàn)获列,子類中重寫該方法必須要添加override關(guān)鍵字。如果特質(zhì)中方法未實(shí)現(xiàn)击孩,則寫不寫override均可
class A extends B with C {
def f = {
super.func()
// 如果特質(zhì)B和C中都有方法func鹏漆,則按照從左到右的優(yōu)先循序,執(zhí)行B中的func方法
super[C].func()
// 明確指明調(diào)用特質(zhì)C中的func方法
}
}
特質(zhì)中出現(xiàn)的具體字段會(huì)被添加到子類中
trait Parent {
val count = 0
}
class Child extends Parent {
// 相當(dāng)于也加入了val count = 0
}
特質(zhì)不能有構(gòu)造器參數(shù)括蝠,每個(gè)特質(zhì)都有一個(gè)無(wú)參數(shù)構(gòu)造器饭聚。
特質(zhì)可以擴(kuò)展類秒梳,該類會(huì)自動(dòng)成為混入該特質(zhì)的類的超類
自身類型:
特質(zhì)可以以如下代碼開始:
this: 類型A =>
...
如此定義的特質(zhì)只能被混入類型A的子類當(dāng)中
自身類型也可以處理結(jié)構(gòu)類型:
trait A {
this: {def getMessage(): Unit} =>
...
// 只有具有g(shù)etMessage方法的類才能混入該特質(zhì)
}
yield事scala的保留字箕速,如果調(diào)用java的方法中包含該單詞朋譬,需要反引號(hào)。例如:Thread.yield
定義前置操作符:
class A {
def unary_-(): Unit = {}
}
調(diào)用該前置操作符時(shí)可使用:-a字柠,相當(dāng)于a.unary_-
用于構(gòu)造列表的::操作符是右結(jié)合的:
1 :: 2 :: Nil
的意思是1 :: (2 :: Nil)
2 :: Nil
相當(dāng)于Nil.::(2)
函數(shù)調(diào)用語(yǔ)法可以擴(kuò)展到函數(shù)之外的值犀忱,例如:
f(x, y, z)
相當(dāng)于調(diào)用f.apply(x, y, z)
f(x, y, z) = value
相當(dāng)于調(diào)用f.update(x, y, z, value)
提取器:
class Fraction(val num: Int, val den: Int)
object Fraction {
def unapply(input: Fraction): Option[(Int, Int)] = {
if (input.den == 0) None else Some((input.num, input.den))
}
}
val Fraction(a, b) = new Fraction(3, 4) // a 為 3, b 為 4
// unapply方法用在賦值語(yǔ)句和模式匹配中
unapplySeq方法:匹配任意長(zhǎng)度序列
將函數(shù)本身賦予一個(gè)變量:
import math._
val fun = ceil _
匿名函數(shù):
(x: Double) => 3 * x
函數(shù)參數(shù)可以放在大括號(hào)中:
Array(1, 2, 3).map((x: Int) => 3 * x)
Array(1, 2, 3).map{(x: Int) => 3 * x}
函數(shù)接收函數(shù)為參數(shù):
def f(g: (Int) => Int) = g(10)
f((x: Int) => 3 * x)
x的類型可推斷為Int阴汇,因此類型可以省略為:
f((x) => 3 * x)
參數(shù)列表中只有一個(gè)參數(shù)数冬,小括號(hào)可以省略:
f(x => 3 * x)
參數(shù)在=> 右側(cè)僅出現(xiàn)了一次,可以省略為:
f(3 * _) // 簡(jiǎn)寫方式僅能在參數(shù)類型已知的情況下有效
函數(shù)柯里化:
def mulOneAtATime(x: Int)(y: Int) = x * y
mulOneAtATime(3)(4)
柯里化的用途之一:提供更多的類型推斷信息
val a = Array("Hello", "World")
val b = Array("hello", "world")
a.corresponds(b)(_.equalsIgnoreCase(_))
corresponds的定義為:
def corresponds[B](that: Seq[B])(p: (A: B) => Boolean):Boolean
可以根據(jù)第一個(gè)參數(shù)傳進(jìn)去的類型B搀庶,以用于第二個(gè)參數(shù)p
def runInThread(block: () => Unit) = {
new Thread {
override def run() {block()}
}.start()
}
runInThread{() => println("")}
可以將參數(shù)列表省略掉:
def runInThread(block: => Unit) = {
new Thread {
override def run() {block} // 調(diào)用時(shí)不需要加括號(hào)
}.start()
}
runInThread{println("")} // 傳遞匿名函數(shù)時(shí)不需要參數(shù)列表
不可變序列:
Indexed: Vector, Range
non-indexed: List, Stream, Stack, Queue
可變序列:
indexed: ArrayBuffer
non-indexed: Stack, Queue, PriorityQueue, LinkedList, DoubleLinkedList
List包含head和tail
List(9, 4, 2) 相當(dāng)于 9 :: 4 :: 2 :: Nil
集合應(yīng)用的view方法返回的是懶視圖拐纱,只對(duì)被求值的時(shí)候進(jìn)行計(jì)算
可以使用force方法對(duì)懶集合進(jìn)行強(qiáng)制計(jì)算
使用線程安全的集合:混入Synchronized開頭的幾個(gè)集合特質(zhì),例如:
val synchronizedMap = new scala.collection.mutable.HashMap[String, Int] with scala.collection.mutable.SynchronizedMap[String, Int]
集合并行計(jì)算:調(diào)用par函數(shù)
for(i <- (0 until 100).par) print(i + " ")
for(i <- (0 until 100).par) yield i + " "
并行集合轉(zhuǎn)換為串行集合:調(diào)用ser方法
模式匹配:
p match {
case '+' => ...
case _: Int => ...
case e: Exception => e.printStackTrace()
case _: Int if p % 2 == 0 => ...
case _ => ... // 相當(dāng)于default
}
match語(yǔ)句也可以是表達(dá)式
for中也可以使用模式:
for((key, "") <- System.getProperties()) {// key為所有值為空白的鍵}
樣例類case class:
樣例類構(gòu)造器每一個(gè)參數(shù)自動(dòng)稱為val哥倔,除非被聲明為var
使用伴生對(duì)象的apply方法創(chuàng)建新對(duì)象
提供unapply方法秸架,可使用模式匹配
生成toString, hasCode, equals和copy方法
copy方法的使用:
case class Person(name: String, age: Int)
val p1 = Person("Paul", 20)
val p2 = p1.copy() // p2為 name="Paul" age=20
val p3 = p1.copy(age=30) // p3 為 name="Paul" age=30
嵌套值綁定到變量:使用@符號(hào)
密封類:
使用樣例類做模式匹配是,編譯器確保已經(jīng)列出了所有可能的選擇
密封類所有的子類都必須在密封類所在的文件中定義
sealed abstract class Direction
case object EAST extends Direction
case object WEST extends Direction
case object NORTH extends Direction
case object SOUTH extends Direction
d match {
case EAST => ...
case WEST => ...
case NORTH => ...
case SOUTH => ...
}
偏函數(shù):被花括號(hào)包圍的一組case語(yǔ)句為偏函數(shù)咆蒿。
val f: PartialFunction[Char, Int] = {case '+' => 1, case '-' => -1}
f('-') // 調(diào)用f.apply('-') 返回 -1
f.isDefinedAt('0') // false 至少匹配其中一個(gè)模式時(shí)返回true
f('0') // 拋出MatchError
Scala XML
scala內(nèi)建支持XML格式
節(jié)點(diǎn)序列的類型為NodeSeq
var xml = <html><head></head><body></body></html>
for (elem <- xml.child) { // 返回xml的子節(jié)點(diǎn)
println(elem)
}
可以使用NodeBuffer的形式在程序中構(gòu)建NodeSeq:
var nodeItems = new NodeBuffer
nodeItems += <ul></ul>
var nodes: NodeSeq = nodeItems // NodeSeq為不可變類型东抹,NodeBuffer可以被隱式轉(zhuǎn)換為NodeSeq
通過attributes方法獲取節(jié)點(diǎn)中的屬性:
var node = <img src="image.jpg"></img>
var imgSrc = node.attributes("src") // 結(jié)果為image.jpg沃测,類型為節(jié)點(diǎn)序列,不是字符串
imgSrc.text // 轉(zhuǎn)換類型為字符串
for (attr <- elem.attributes) {} // 遍歷attr.key和attr.value.text
elem.attributes.asAttrMap // 將屬性轉(zhuǎn)換為Map類型
XML內(nèi)嵌表達(dá)式:
var items = Array("Hello", "World")
val elem = <ul><li>{items(0)}</li><li>{items(1)}</li></ul>
println(elem) // 結(jié)果為<ul><li>Hello</li><li>World</li></ul>
XPath匹配XML節(jié)點(diǎn):
val x = elem \ "li" // 返回elem直接所有一級(jí)子節(jié)點(diǎn)為li的節(jié)點(diǎn)
val x = elem \\ "li" // 返回elem所有類型為li的子節(jié)點(diǎn)
val x = elem \ "_" \ "li" // 返回elem所有二級(jí)子節(jié)點(diǎn),且類型為li
val x = elem \ "@src" // 返回elem節(jié)點(diǎn)的src屬性
val x = elem \\ "@src" // 返回elem節(jié)點(diǎn)所有子類節(jié)點(diǎn)的src屬性
從文件中加載XML
import scala.xml.XML
val xmlFile = XML.loadFile("xmlFile.xml")
泛型類
scala使用中括號(hào)表示泛型類:
class Pair[T, S] (val first: T, val second: S)
泛型函數(shù):
class getMiddle[T](arr: Array[T]) = arr(arr.length / 2)
val fun = getMiddle[String] _ //返回一個(gè)函數(shù)惧互,但是類型被限制為String
泛型上界:
[T <: Type] T必須為Type的子類
泛型下界:
[T >: Type] T必須為Type的超類
視圖界定:
[T <% Type] T可以被隱式轉(zhuǎn)換成Type
基本類型數(shù)組泛型指定:需要將上界指定為Manifest
協(xié)變:對(duì)于Pair[+T]喇伯,如果A是B的子類,那么Pair[A]是Pair[B]的子類管宵。
逆變:對(duì)于Pair[+T]箩朴,如果A是B的子類岗喉,那么Pair[A]是Pair[B]的父類。
函數(shù)在參數(shù)上是逆變的炸庞,在返回值上是協(xié)變的钱床。對(duì)于某個(gè)對(duì)象的消費(fèi)適合逆變,而對(duì)于他的產(chǎn)出則適用于協(xié)變埠居。
單例類型:
class A {
def funA() = {
...
this
}
}
class B extends A {
def funB() = {
...
this
}
}
val b = new B
b.funA.funB // 會(huì)出錯(cuò)查牌,funA返回的this類型為A,A沒有funB方法
將類定義修改為:
class A {
def funA() = {
...
this.type
}
}
class B extends A {
def funB() = {
...
this.type
}
}
val b = new B
b.funA.funB // 無(wú)問題
object A
class B {
def funA(obj: A.type) = {} // 指代的是A這個(gè)單例對(duì)象而不是A這個(gè)類型
}
類型別名:
type MyType = HashMap[Int, String]
結(jié)構(gòu)類型:
def fun(obj: {def f(s: String): Any}) {}
// 具有f(s: String): Any方法的類的實(shí)例才能作為該方法的參數(shù)滥壕。(scala使用反射來調(diào)用該方法)
復(fù)合類型:T1 with T2 with T3 ...
自身類型:
trait MyExceptionTrait {
this: Exception =>
...
// this被當(dāng)做Exception對(duì)象來對(duì)待
}
MyExceptionTrait 特質(zhì)只能被混入Exception及其子類中
抽象類型:
trait A{
type Content
def make(): Content
}
class B extends A {
type Content = String // 必須指定類型
def make():String = {}
}
隱式轉(zhuǎn)換:
package com.paul
class Fraction(val x:Int, val y: Int) {
def *(another: Fraction) = {...}
}
object Fraction {
def apply(val x:Int, val y: Int) = new Fraction(x, y)
}
package com.paul
object FractionConversion {
implicit def int2Fraction(n: Int) = Fraction(n, 1)
}
class Demo extends App {
import com.paul.FractionConversion._
val result = 3 * Fraction(3, 2) // 隱式調(diào)用int2Fraction
}
隱式參數(shù):
case class Delimeter(val left: String, val: right: String)
class Tools {
implicit val delimeter = Delimeter("<<", ">>")
def makeString(s: String)(implicit delim: Delimeter) = {
// demimeter會(huì)被隱式的賦予delim
}
}