第一题
package p1{
class Bug{
private var pos: Int = 0
private var direct: Int = 1
def move(p: Int) = {
this.pos += p * direct
this
}
def show() = {
print(this.pos + " ")
this
}
def turn() = {
this.direct *= -1
this
}
}
object Main extends App {
val bugsy = new Bug()
bugsy.move(4).show().move(6).show().turn().move(5).show()
}
}
第二题
package p2{
object Show
object Then
object Around
class Bug{
private var pos: Int = 0
private var direct: Int = 1
def move(p: Int) = {
this.pos += p * direct
this
}
def turn(obj: Around.type) = {
this.direct *= -1
this
}
def and(obj: Show.type) = {
print(this.pos + " ")
this
}
def and(obj: Then.type) = this
}
object Main extends App{
val bugsy: Bug = new Bug()
bugsy move 4 and Show and Then move 6 and Show turn Around move 5 and Show
}
}
第三题
package p3{
object Title
object Author
class Document {
var title: String = _
var author: String = _
private var useNextArgAs: Any = null
def set(obj: Title.type): this.type = {
useNextArgAs = obj
this
}
def set(obj: Author.type): this.type = {
useNextArgAs = obj
this
}
def to(arg: String): this.type = {
if(useNextArgAs == Title) title = arg
else if(useNextArgAs == Author) author = arg
this
}
override def toString = "Title: " + title + ", author: " + author;
}
class Book extends Document{
def addChapter(chapter: String) = {
this
}
}
object Main extends App{
val book = new Book()
book set Title to "Scala for the Impatient" set Author to "Cay Horstmann"
println(book)
}
}
第四题
package p4{
import scala.collection.mutable.ArrayBuffer
class Network {
// 参考 5.9节
outer =>
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
override def equals(other: Any): Boolean = {
other match {
// 参考 “路径” 章节,一个网络对应的Member的路径是outer.Member
// case self: Network.this.Member => true // 这个ok
// case self: outer.Member => true // 这个ok
case self: Member => true // 深入理解路径
case _ => false
}
}
}
private val members = new ArrayBuffer[Member]
def join(name: String) = {
val m = new Member(name)
members += m
m
}
}
object Main extends App{
val chatter = new Network
val myFace = new Network
val fred = chatter.join("Fred")
val barney = myFace.join("Barney")
var jiexray = chatter.join("jiexray")
println(fred equals barney)
println(fred equals jiexray)
}
}
第五题
package p5{
import scala.collection.mutable.ArrayBuffer
import scala.language.existentials
class Network {
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
}
private val members = new ArrayBuffer[Member]
def join(name: String) = {
val m = new Member(name)
members += m
m
}
}
object Main extends App {
type NetworkMember = n.Member forSome{val n: Network}
def process(m1: NetworkMember, m2: NetworkMember) = (m1, m2)
val chatter = new Network
val myFace = new Network
val fred = chatter.join("Fred")
val barney = myFace.join("Barney")
var jiexray = chatter.join("jiexray")
process(fred, barney)
process(fred, jiexray)
}
/*
解释:This is because for `process`, there's no relation
between the two different variables `n` in the type alias `NetworkMember`.
thanks: https://github.com/asarkar/scala-impatient/blob/master/src/main/scala/name/abhijitsarkar/scala/scalaimpatient/types/Network.scala
*/
}
第六题
package p6{
import scala.math._
object Main extends App{
def find(sortedArr: Array[Int], num: Int): Int Either Int = {
var distance = Int.MaxValue
var ans = 0
for(i <- 0 until sortedArr.length){
if(abs(sortedArr(i) - num) >= distance){
if(sortedArr(ans) == num) return Left(ans)
else return Right(ans)
}else{
ans = i
distance = abs(sortedArr(i) - num)
}
}
// not find return last index
if(sortedArr(ans) == num) return Left(ans)
else return Right(ans)
}
def get(res: Either[Int, Int]) = res match {
case Left(v) => println("find: " + v)
case Right(v) => println("find most reached: " + v)
}
val arr = Array(1,3,4,15,16,27,38)
val res1 = find(arr, 15)
get(res1)
val res2 = find(arr, 10)
get(res2)
val res3 = find(arr, 40)
get(res3)
}
}
第七题
package p7 {
import scala.language.reflectiveCalls
object Main extends App{
def invoke[T <: {def close(): Unit}](target: T, fun: (T) => Unit) {
try{
fun(target)
} catch{
case ex: Exception => target.close; ex.printStackTrace
}finally{
target.close
}
}
object Test1{
def close(){
println("Test1 is closed")
}
}
object Test2{
}
def func(arg: Test1.type){
println("Test is operated")
}
def func1(arg: Test2.type){
println("Test2 is operated")
}
def func2(arg: {def close(): Unit}) {
println("Test is operated by func2")
}
invoke(Test1, func)
invoke(Test1, func2)
// Test2 cannot match type parameter T
// invoke(Test2, func1)
}
}
第八题
package p8{
import scala.language.reflectiveCalls
object Main extends App {
def printValues(f: {def apply(n: Int):Int}, from: Int, to: Int) {
for(i <- from to `to`) print(f(i) + " ")
print("\n")
}
def printValues2(f: (Int) => (Int), from: Int, to: Int) {
for(i <- from to `to`) print(f(i) + " ")
print("\n")
}
printValues2((x: Int) => x * x, 3, 6)
printValues(Array(1,1,2,3,5,8,13,21,34,55), 3, 6)
}
/* more information:
https://stackoverflow.com/questions/45049928/using-structural-type-in-scala-occurs-nosuchmethodexception
*/
}
第九题
package p9{
/*
Ch18.scala:300: error: illegal inheritance;
self-type ch18.p9.Meters does not conform to ch18.p9.Dim[ch18.p9.Seconds]'s selftype ch18.p9.Dim[ch18.p9.Seconds] with ch18.p9.Seconds
class Meters(v: Double) extends Dim[Seconds](v, "m"){
^
one error found
*/
abstract class Dim[T](val value: Double, val name: String){
this: T =>
protected def create(v: Double): T
def +(other: Dim[T]) = create(value + other.value)
override def toString = value + " " + name;
}
class Seconds(v: Double) extends Dim[Seconds](v, "s"){
override val value = v
override def create(v: Double) = new Seconds(v)
}
// class Meters(v: Double) extends Dim[Seconds](v, "m"){
// override def create(v: Double) = new Seconds(v)
// }
object Main extends App {
val s1 = new Seconds(10)
val s2 = new Seconds(10)
// val m = new Meters(10)
// println(s1 + m)
println(s1 + s2)
}
}
第十题
看不懂啊