控制結構和函式 |
1. 編寫示例程式,展示為什麼
package com.horstmann.impatient
不同於
package com
package horstmann
package impatient
描述: 區別是後者的上層包也可見,而串寫的只有當前包範圍可見
程式程式碼: b.scala
-
package com{
-
package horstmann{
-
object A{
-
def hi=println("I am A")
-
}
-
package impatient{
-
object B extends App{
-
def hi=A.hi
-
hi
-
}
-
}
-
}
-
}
執行結果:
E:\Test>scalac b.scala
E:\Test>scala com.horstmann.impatient.B
I am A
E:\Test>
程式程式碼: c.scala
package com.horstmann.impatient{
object C extends App{
B.hi
A.hi
}
}
執行結果:
E:\Test>scalac c.scala
c.scala:4: error: not found: value A
A.hi
^
one error found
E:\Test>
編譯時找不到A,說明串聯宣告時不包含上級宣告
程式程式碼: d.scala
E:\Test>scalac d.scala
E:\Test>scala com.horstmann.impatient.C
I am A
I am A
E:\Test>
2. 編寫一段讓你的Scala朋友們感到困惑的程式碼,使用一個不在頂部的com包
程式程式碼: a1.scala
package com {
package horstmann {
package com {
package horstmann {
object A {
def hi = println("I am the Ghost A")
}
}
}
}
}
程式程式碼: a2.scala
package com {
package horstmann {
object A {
def hi =println("I am A")
}
package impatient {
object B extends App {
def hi = com.horstmann.A.hi
hi
}
}
}
}
先編譯a2.scala再編譯a1.scala執行結果如下:
E:\Test>scalac a2.scala
E:\Test>scalac a1.scala
E:\Test>scala com.horstmann.impatient.B
I am A
E:\Test>
先編譯a1.scala再編譯a1.scala執行結果如下:
E:\Test>scalac a1.scala
E:\Test>scalac a2.scala
E:\Test>scala com.horstmann.impatient.B
I am the Ghost A
E:\Test>
3. 編寫一個包random,加入函式nextlnt(): Int、nextDouble(): Double和setSeed(seed : Int): Unit。生成隨機數的演算法採用線性同餘生成器:
後值 =(前值×a+b)mod 2n
其中,a = 1664525,b =1013904223,n =32,前值的初始值為seed。
程式程式碼:
-
package random{
-
object Random {
-
private val a = 1664525
-
private val b = 1013904223
-
private val n = 32
-
-
private var seed=0
-
private var follow:BigInt=0
-
private var previous:BigInt=0
-
-
def nextInt():Int={
-
follow=(previous*a+b)%BigInt(math.pow(2, n).toLong)
-
previous=follow
-
(follow%Int.MaxValue).intValue()
-
}
-
def nextDouble():Double={
-
nextInt.toDouble
-
}
-
def setSeed(newSeed:Int){
-
seed=newSeed
-
previous=seed
-
}
-
}
-
}
-
object Test extends App{
-
var r =random.Random
-
r.setSeed(args(0).toInt)
-
for(i <- 1 to 10) println(r.nextInt())
-
for(i <- 1 to 10) println(r.nextDouble())
-
}
執行結果:
E:\Test>scalac Random.scala
E:\Test>scala Test 0
1013904223
1196435762
1372387050
720982837
1649599747
523159175
1476291629
601448361
33406696
351317787
1.27442629E9
1.020336477E9
4.8889166E8
1.654060783E9
2.8987765E7
6.3353937E7
8.92205936E8
1.338634754E9
1.649346937E9
6.21388933E8
E:\Test>
4. 在你看來,Scala的設計者為什麼要提供package object法而不是簡單地讓你將函式和變數新增到包中呢
直接加函式和變數宣告到包中,比如com.a.b.c。這樣就跟c下面的的class或者object差 了一個層級。他們實際上是c下面的所有類的共同的上級定義。這樣一來就沒有了封裝性。 而實現上來說估計也比較麻煩。
5. private[com] def giveRaise(rate: Double)的含義是什麼,有用嗎
該函式在com包下可見,可以擴大函式的可見範圍
6. 編寫一段程式,將Java雜湊對映中的所有元素拷貝到Scala雜湊對映。用引入語句重新命名這兩個類
程式程式碼:
-
import java.util.{HashMap=>JHashMap}
-
import scala.collection.mutable.HashMap
-
object JavaMap {
-
def transMapValues(javaMap:JHashMap[Any,Any]):HashMap[Any,Any]={
-
val result=new HashMap[Any,Any]
-
for(k <- javaMap.keySet().toArray()){
-
result+=k->javaMap.get(k)
-
}
-
result
-
}
-
def main(args: Array[String]): Unit = {
-
val jmap:JHashMap[Any,Any]=new JHashMap[Any,Any]
-
var smap=new HashMap[Any,Any]
-
for(i <- 1 to 9)
-
jmap.put(i,"JavaMap"+i)
-
smap=transMapValues(jmap)
-
smap.foreach(println)
-
}
-
}
執行結果:
(8,JavaMap8)
(2,JavaMap2)
(5,JavaMap5)
(4,JavaMap4)
(7,JavaMap7)
(1,JavaMap1)
(9,JavaMap9)
(3,JavaMap3)
(6,JavaMap6)
7. 在前一個練習中,將所有引入語句移動到儘可能小的作用域裡
描述:import可以放到任何區域,直接放到物件結構體當中,也沒有問題
程式程式碼:
-
object JavaMap {
-
import java.util.{HashMap=>JHashMap}
-
import scala.collection.mutable.HashMap
-
def transMapValues(javaMap:JHashMap[Any,Any]):HashMap[Any,Any]={
-
val result=new HashMap[Any,Any]
-
for(k <- javaMap.keySet().toArray()){
-
result+=k->javaMap.get(k)
-
}
-
result
-
}
-
def main(args: Array[String]): Unit = {
-
val jmap:JHashMap[Any,Any]=new JHashMap[Any,Any]
-
var smap=new HashMap[Any,Any]
-
for(i <- 1 to 10)
-
jmap.put(i,"JavaMap"+i)
-
smap=transMapValues(jmap)
-
smap.foreach(println)
-
}
-
}
8. 以下程式碼的作用是什麼,這是個好主意嗎
import java._
import javax._
引入了java和javax的所有內容。因為Scala會自動覆蓋java的同名類,不會有衝突。即使這樣,引入過多的包,也會讓人很迷惑。況且scala編譯就已經夠慢的了
9. 編寫一段程式,引人java.lang.System類,從user.name系統屬性讀取使用者名稱,從Console物件讀取一個密碼,如果密碼不是" secret",則在標準錯誤流中列印一個訊息;如果密碼是" secret",則在標準輸出流中列印一個問候訊息。不要使用任其他引入,也不要使用任何限定詞,即帶句點的那種
程式程式碼:
-
object Sys{
-
import scala.io.StdIn
-
import java.lang.System._
-
def main(args: Array[String]): Unit = {
-
val pass=StdIn.readLine()
-
if(pass=="secret"){
-
val name=getProperty("user.name")
-
out.printf("Greetings,%s!",name)
-
}else{
-
err.println("error")
-
}
-
}
-
}
執行結果:
secret
Greetings,hadoop!
10. 除了StringBuilder,還有那些java.lang的成員是被scala包覆蓋的
Console,Math, 還有基本型別包裝物件,Long,Double,Char,Short等等都被Scala覆蓋了。
如果,您認為閱讀這篇部落格讓您有些收穫,不妨點選一下右下角的【推薦】。
如果,您希望更容易地發現我的新部落格,不妨點選一下左下角的【關注我】。
如果,您對我的部落格所講述的內容有興趣,請繼續關注我的後續部落格,我是【Sunddenly】。本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。