1. 程式人生 > >《快學Scala》習題詳解 第7章 包

《快學Scala》習題詳解 第7章 包

1 編寫示例程式,展示為什麼

package com.horstmann.impatient

不同於

package com
package horstmann
package impatient
package a.b.c {
  //串聯式包語句
  object cat {
    //一旦使用串聯式語句,父包內容不可見
    dog.toString()
    fa.toString()
  }
}
//同一檔案定義多個包時,使用{}包起來,否則易出錯 
package a.b {
  object fa {}
}
// 檔案頂部標記法
package a
package
b package c //等同於package a.b // package c object dog { cat.toString() fa.toString() //上一級包中的內容可見 }

2 編寫一段讓你的Scala朋友們感到困惑的程式碼,使用一個不在頂部的com包

object cat {
  //可在任何地方引入,不限於頂部,作用效果作該語句塊的末端
  import a.b._
  fa.toString()
}
package a.b {
  object fa {}
}

3 編寫一個包random,加入函式nextInt():Int,nextDouble():Double,setSeed(seed:Int):Unit。生成隨機數的演算法採用線性同餘生成器:
後值 = (前值 * a + b)mod 2^n
其中,a = 1664525,b=1013904223,n = 32,前值的初始值為seed
網上的答案基本都是錯誤的,壓根不是同餘法
以下是Java中隨機數的生成,改成scala太費時就不改了,而且scala生成隨機數,底層就是呼叫Java的Random
包物件中不能使用main/App,定義了也不會執行

    protected int next(int bits) {
        long oldseed, nextseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            nextseed = (oldseed * multiplier + addend) & mask;
        } while (!seed.compareAndSet(oldseed, nextseed));
        return (int)(nextseed >>> (48
- bits)); }

4 在你看來Scala的設計者為什麼要提供package object語法而不是簡單的讓你將函式和變數新增到包中呢?
因為JVM不支援包中包含函式和變數
放在同一個object中,同時便於管理

5 private[com] def giveRaise(rate:Double)的含義是什麼?有用嗎?
包的可見性,沒有被宣告為public/private/protected的類成員在包含該類的包中可見
private[com],將類成員的可見度延展到上層包com,即可以使用giveRaise方法

6 編寫一段程式,將Java雜湊對映中的所有元素拷貝到Scala雜湊對映。用引入語句重新命名這兩個類。

  import java.util.{ HashMap => M1 }
  import scala.collection.mutable.{ HashMap => M2 }
  val m1 = new M1[String, Integer]
  m1.put("a", 1)
  m1.put("b", 2)
  m1.put("c", 2)
  val m2 = new M2[String, Int]
  for (key <- m1.keySet().toArray()) {
    m2 += (key.toString() -> m1.get(key).toInt)
  }
  for ((k, v) <- m2) println(k + ":" + v)

7 在前一個練習中,將所有引入語句移動到儘可能小的作用域裡
同上

8 以下程式碼的作用是什麼?這是個好主意嗎?
import java._
import javax._
匯入java與javax包中所有成員,不好,包中內容會衝突,但包下面全為子包

9 編寫一段程式,引入java.lang.System類,從user.name系統屬性讀取使用者名稱,從Console物件讀取一個密碼,如果密碼不是”secret”,則在標準錯誤流中列印一個訊息;如果密碼是”secret”,則在標準輸出流中列印一個問候訊息。不要使用任何其他引入,也不要使用任何限定詞(帶句點的那種)

  //java.lang._預設匯入
  val password = Console.readLine()
  if (password == "secret") println("Hello " + System.getProperty("user.name"))
  else println("error")

10 除了StringBuilder,還有哪些java.lang的成員是被scala包覆蓋的?
scala中,比如基本資料型別,String
scala有很多語法都是對Java的封裝,應該能從專門技術文件下查到,逐個對比,不太現實