一个构建有理数的scala例子
class Rational(n: Int, d: Int) {
require(d!=0)
private val g = gcd(n.abs, d.abs) //最大公约数
val numer: Int = n / g
val denom: Int = d / g
def this(n: Int) = this(n, 1)
override def toString = numer + "/" + denom
def add(that: Rational): Rational =
new Rational(numer*that.denom+that.numer*denom,
denom * that.denom)
def +(that: Rational): Rational = add(that)
def mul(that: Rational): Rational =
new Rational(numer*that.numer, denom*that.denom)
def *(that: Rational): Rational = mul(that)
def sub(that: Rational): Rational = add(new Rational(-that.numer, that.denom))
def -(that: Rational): Rational = sub(that)
def div(that: Rational): Rational = mul(new Rational(that.denom, that.numer))
def /(that: Rational): Rational = div(that)
private def gcd(a: Int, b: Int): Int =
if(b == 0) a else gcd(b, a % b)
}
调用:
object test {
//下面这个函数是为了实现将整数隐式转换为有理数,在有必要的时候。
implicit def IntToRational(i: Int) = new Rational(i)
def main(args: Array[String]) {
val a = new Rational(1,2)
val b = new Rational(3, 5)
val c = 2 * b
println(c)
}
}
简单的流程控制
val filesHere = (new java.io.File("./src")).listFiles()
for (f <- filesHere if f.getName.endsWith(".scala"))
println(f)
//下面这句话和上面的其实是等价的!
filesHere.foreach(f => println(if (f.getName.endsWith(".scala")) f))
//也可以对for循环安装多个if过滤
for (f <- filesHere if f.getName.endsWith(".scala"); if f.getName.length > 3)
println(f)
object test{
def main(args: Array[String]) {
val filesHere = (new java.io.File("./src")).listFiles()
for (f <- filesHere if f.getName.endsWith(".scala"); if f.getName.length > 3)
println(f)
filesHere.foreach(f => println(if (f.getName.endsWith(".scala") && f.getName.length > 3) f))
def fileLines(file: java.io.File) =
scala.io.Source.fromFile(file).getLines.toList
def grep(pattern: String) =
for {
file <- filesHere //这个是第一层循环
if file.getName.endsWith(".scala")
line <- fileLines(file = file) //注意这里是第二层循环
trimmed = line.trim
if trimmed.matches(pattern)
} println(file +": " + trimmed)
grep(".*gcd.*")
}
}
trait的混入
在scala中,可以通过混入特质来更新子类的行为,但是又不需要修改父类,这样可以轻松的更新功能,下面就演示一个《scala编程》中的例子:
import scala.collection.mutable.ArrayBuffer
/**
* Created on 2016/10/5.
*/
abstract class IntQueue{
def get: Int
def put(x: Int): Unit
}
trait Doubling extends IntQueue{
abstract override def put(x: Int): Unit = {super.put(2*x)}
}
trait Increment extends IntQueue{
abstract override def put(x: Int): Unit = {super.put(x + 1)}
}
trait Filter extends IntQueue{
abstract override def put(x: Int): Unit = {if(x > 0) super.put(x)}
}
class BasicIntQueue extends IntQueue {
private val buf = new ArrayBuffer[Int]
def get = buf.remove(0)
def put(x: Int) { buf += x }
}
class StandardIntQueue extends BasicIntQueue with Increment with Doubling with Filter
这里定义了一个抽象类IntQueue
,然后定义了一个基类BasicIntQueue
,然后定义了三个trait
,但是都是extends IntQueue
,所以,它们只用用来修饰继承了IntQueue
的子类。这里的BasicIntQueue
是不能直接用这三个 trait来修饰的。IntQueue
是一个抽象类,所以继承类必须实现抽象类的所有方法,如果直接用trait
修饰BasicIntQueue
,则与BasicIntQueue
中的put方法冲突。
object MyInt {
def main(args: Array[String]): Unit = {
val sq = new StandardIntQueue
sq.put(10)
sq.put(2)
println(sq.get)
println(sq.get)
}
}
另外需要说明的是,多个trait
作用时,是最右边的开始起作用,然后从右到左。