因?yàn)橛螒蛞鰤毫y(cè)試,用scala寫機(jī)器人http://www.scala-lang.org/ http://www.ibm.com/developerworks/cn/java/j-scala/
http://download.scala-ide.org/
Scala程序設(shè)計(jì):Java虛擬機(jī)多核編程實(shí)戰(zhàn)
Scala編程
《Programming Scala》
《Programming in Scala》
目前參考Scala編程電子版-書籍已購買
學(xué)習(xí)方法:首先看一下基礎(chǔ)知識(shí),然后結(jié)合robot,遇到不會(huì)的地方查詢書籍或者網(wǎng)絡(luò)
關(guān)于Scala的函數(shù)式編程-
函數(shù)式編程有兩種指導(dǎo)理念,第一種理念是函數(shù)是第一類值。在函數(shù)式語言中,函數(shù)也是值,與整數(shù)或字符串處在同一個(gè)地位。函
數(shù)可以被當(dāng)作參數(shù)傳遞給其他函數(shù),可以當(dāng)作結(jié)果從函數(shù)中返回或保存在變量里??梢栽诤瘮?shù)里定義其他函數(shù),就好像在函數(shù)里定
義整數(shù)一樣。還可以定義匿名函數(shù),并隨意地插入到代碼的任何地方。
函數(shù)式編程的第二種理念是程序的操作應(yīng)該把輸入值映射為輸出值而不是就地修改數(shù)據(jù)。如,在Java 和Scala 里,字符串是一
種數(shù)學(xué)意義上的字符序列。使用s.replace(';', '.')這樣的表達(dá)式替換字符串里的字符會(huì)產(chǎn)生一個(gè)新的,不同于原字符串s 的對(duì)象。換句
話說就是在Java 里字符串是不可變的,(immutable)而在Ruby 里則是可變的。因此單就字符串來說,Java 是函數(shù)式的語言,而Ruby
不是。不可變數(shù)據(jù)結(jié)構(gòu)是函數(shù)式語言的一塊基石。
函數(shù)式編程第二種理念的另一種解釋是方法不應(yīng)有任何副作用(side effect)。方法與其所在環(huán)境交流的唯一方式應(yīng)該是獲得
參數(shù)和返回結(jié)果。比如Java 里String 類的replace 方法就符合這種說法。它的參數(shù)包括一個(gè)字符串和兩個(gè)字符,返回的是一個(gè)新的字
符串,其中的指定字符都替換成另一個(gè)。調(diào)用replace 不會(huì)有其他的結(jié)果。類似于replace 這樣的方法被稱為指稱透明
(referentially transparent),就是說對(duì)于任何輸入來講,都可以用方法的結(jié)果替代對(duì)它的調(diào)用,而不影響程序的語義。
1.去http://www.scala-lang.org/下載scala發(fā)布包,scala-2.9.1.final.zip,解壓,bin目錄下有scala.bat-解釋器批處理文件。學(xué)習(xí)習(xí)Scala 最簡單的方
法就是使用Scala 解釋器,它是編寫Scala 表達(dá)式和程序的交互式“shell”。只要在解釋器里輸入表達(dá)式,它就能計(jì)算并打印結(jié)果值。
Scala 的交互式shell 就叫做scala。(或者將scala的bin目錄加到path中,然后就可以在cmd中運(yùn)行scala,輸入scala -version可以查看版本)
2.Int 類型指代了scala 包的類Int,類Int 的值對(duì)應(yīng)著Java 的int 值。從更廣泛意義上來說,所有的Java 原始類型在scala 包里都有對(duì)應(yīng)的類。
例如,scala.Boolean 對(duì)應(yīng)著Java 的boolean。scala.Float 對(duì)應(yīng)著Java 的float。在把Scala 代碼編譯成Java 字節(jié)碼的時(shí)候,Scala 編譯器會(huì)
代以使用Java 的原語類型以便優(yōu)化性能。
3.println 函數(shù)在標(biāo)準(zhǔn)輸出上打印傳給它的字符串,就跟Java 里的System.out.println 一樣。
4.Scala 有兩種變量,val 和var。val 類似于Java 里的final 變量。一旦初始化了,val 就不能再被賦值。相反,var 如同Java 里面的非final
變量,可以在它的生命周期中被多次賦值。
如scala> val msg = "Hello, world!"
msg: java.lang.String = Hello, world!
這個(gè)語句引入了msg 作為字符串"Hello, world!"的名字。它的類型是java.lang.String,因?yàn)镾cala 的字符串是由Java 的String 類實(shí)現(xiàn)。
5.寫明類型標(biāo)注不但可以確保Scala 編譯器使用你想要用的類型,還可以有助于之后代碼的閱讀。Java 的變量類型寫在名稱之前,相
反,Scala 的變量類型在其名稱之后,用冒號(hào)分隔。
如:scala> val msg2: java.lang.String = "Hello again, world!"
在Scala 程序里java.lang 類型的簡化名4也是可見的,
如:val msg3: String = "Hello yet again, world!"
由于msg 不是var 類型變量,因此唯一不能做的就是再給它賦值,否則編譯器報(bào)錯(cuò)-error: reassignment to val
如果需要的是可以被重新賦值的變量,你應(yīng)該使用var
在解釋器中跨行輸入語句的話,只要一行行寫進(jìn)去即可。如果輸?shù)叫形策€沒結(jié)束,解釋器將在下一行回應(yīng)一個(gè)豎線(按回車即可)。
scala> val multiLine =
| "This is the next line."
如果你發(fā)現(xiàn)了一些錯(cuò)誤而解釋器仍在等著更多的輸入,你可以通過按兩次回車取消掉
scala> val oops =
|
|
You typed two blank lines. Starting a new command.
6.函數(shù)定義-
scala> def max(x: Int, y: Int): Int =
{
if (x > y) x
else y
}
max: (Int,Int)Int
函數(shù)的定義以def 開始。然后是函數(shù)名,本例中是max,跟著是括號(hào)里帶有冒號(hào)分隔的參數(shù)列表。函數(shù)的每個(gè)參數(shù)都必須帶有前綴冒
號(hào)的類型標(biāo)注,因?yàn)镾cala 編譯器(以及解釋器,但之后我們將只說編譯器)無法推斷函數(shù)的參數(shù)類型。在max 參數(shù)列表的括號(hào)之后
你會(huì)看到另一個(gè)“: Int”類型標(biāo)注。這是max 函數(shù)的結(jié)果類型(result type)定義。跟在函數(shù)結(jié)果類型之后的是一個(gè)等號(hào)和一對(duì)包含了函
數(shù)體的大括號(hào)。
Scala 的條件表達(dá)式可以像Java 的三元操作符那樣生成結(jié)果值。例如,Scala 表達(dá)式“if(x > y) x else y”可以與Java 的“(x > y) ? x : y”產(chǎn)
生同樣的結(jié)果。
函數(shù)大括號(hào)前的等號(hào)可以提示我們,按照函數(shù)式編程的風(fēng)格來看,函數(shù)是對(duì)能產(chǎn)生值的表達(dá)式的定義。
既不帶參數(shù)也不返回有用結(jié)果的函數(shù)定義:
scala> def greet() = println("Hello, world!")
greet: ()Unit
函數(shù)greet()定義之后,解釋器輸出返回greet: ()Unit。“greet”當(dāng)然是函數(shù)名,空白的括號(hào)說明函數(shù)不帶參數(shù)。Unit 是greet 的結(jié)果類型,
指的是函數(shù)沒有有效的返回值。Scala 的Unit類型比較類似于Java 的void 類型,而且實(shí)際上Java 里返回void 的方法都會(huì)被映射為返回
Unit的Scala 方法。因此結(jié)果類型為Unit 的方法,并非是為了得到返回值,而是為了其他的運(yùn)行效果(side effect)。greet()的例子里,效
果就是在標(biāo)準(zhǔn)輸出上打印一句話。
如果想要離開解釋器,輸入:quit 或者:q。
7.編寫Scala腳本:
腳本就是一種經(jīng)常會(huì)被執(zhí)行的放在文件中的句子序列。
把以下代碼放在hello.scala 文件中:
println("Hello, world, from a script!")
然后運(yùn)行:
$ scala hello.scala
于是系統(tǒng)又會(huì)輸出:Hello, world, from a script!
Scala 腳本的命令行參數(shù)保存在名為args 的Scala 數(shù)組中。Scala 里,數(shù)組以零開始,可以通過在括號(hào)里指定索引值來訪問數(shù)組元素。
Scala 里數(shù)組steps 的第一個(gè)元素是steps(0),而不是像Java那樣的steps[0]。
// 向第一個(gè)參數(shù)打招呼
println("Hello, " + args(0) + "!")
然后運(yùn)行:$ scala helloarg.scala planet
這個(gè)腳本包含了一條注釋。Scala 編譯器忽略從//開始到行尾截止的以及在/*和*/之間的字符。本例還演示了String 使用+操作符
的連接。
注:1.因?yàn)楝F(xiàn)在已經(jīng)開始編寫腳本了,所以決定采用eclipse的scala插件;org.scala-ide.sdt.update-site。裝上后回彈出Setup
Diagnostics->修改eclipse.ini中-Xmx和-Xms,默認(rèn)推薦的Xmx是1024m,不過那樣eclipse可能都無法啟動(dòng),failed to create the java virtual
machine ,因?yàn)榉峙涞膬?nèi)存過大。
2.如何執(zhí)行腳本:目錄問題。將scala放到c盤,然后將其bin目錄放到path中。然后根目錄中新建一個(gè)script目錄,這個(gè)目錄用
來存放執(zhí)行的一些腳本。若執(zhí)行這些腳本,則需進(jìn)入控制臺(tái),cd到script目錄,然后輸入scala命令執(zhí)行即可。
3.eclipse開發(fā)scala和java差不多,多多嘗試即可。
8.用while 做循環(huán);用if 做判斷
var i = 0
while (i < args.length)
{
println(args(i))
i += 1
}
注:請(qǐng)注意Java 的++i 和i++在Scala 里不起作用,要在Scala 里得到同樣效果,必須要么寫成i = i + 1,要么寫成i += 1
var i = 0
while (i < args.length)
{
if (i != 0)
print(" ")
print(args(i))
i += 1
}
println()
新版本里,print 調(diào)用替代了println 調(diào)用,這樣參數(shù)就可以在同一行里輸出;注意Scala 和Java 一樣,必須把while 或if 的布爾表達(dá)式
放在括號(hào)里;盡管Scala 也和Java 一樣用分號(hào)分隔語句,但是Scala 的分號(hào)經(jīng)常是可選的,因此你的右小手指可以不用那么累。不
過如果你喜歡,也可以把所有可選部分都加上。
9.用foreach 和for 做枚舉
前一步里寫的while 循環(huán)的編碼風(fēng)格被稱為是指令式(imperative)編程。這種風(fēng)格常見于Java,C++和C 這些語言,或者逐條執(zhí)行指
令,或者循環(huán)枚舉,并經(jīng)常改變不同函數(shù)之間的共享狀態(tài)。Scala 里允許使用指令式的編程風(fēng)格,但隨著你對(duì)Scala 的深入了解,你
可能會(huì)發(fā)現(xiàn)自己逐漸傾向于一種更為函數(shù)式(functional)的編程風(fēng)格。
函數(shù)式語言的主要特征之一就是,函數(shù)是第一類結(jié)構(gòu),而這也正是Scala 的主要特征。舉例來說,另一種更為簡潔的打印每
個(gè)命令行參數(shù)的方法是:
args.foreach(arg => println(arg))
args.foreach((arg: String) => println(arg))
這行代碼對(duì)args 調(diào)用了foreach 方法,并把函數(shù)作為參數(shù)傳入,在這里是名為arg 的函數(shù)文本(function literal)。函數(shù)體是println(arg)
綜上,函數(shù)文本的語法構(gòu)成包含,括號(hào)及命名參數(shù)列表,右箭頭以及函數(shù)體
(x: Int, y: Int) => x + y
for (arg <- args)
println(arg)
例子中“for”之后的括號(hào)包含arg<-args。<-右側(cè)的是已經(jīng)在前面見過的args 數(shù)組。<-左側(cè)的“arg”,是val 的名稱(不是var)。(這里一
定是val,因此只寫arg 即可,無需寫成val arg。)盡管arg 可能感覺像var,因?yàn)槊看蚊杜e都會(huì)得到新的值,但這的確是val,因?yàn)樗?/span>
能在for表達(dá)式的函數(shù)體中被重新賦值。所以,對(duì)于args 數(shù)組的每個(gè)元素,枚舉的時(shí)候都會(huì)創(chuàng)建并初始化新的arg 值,然后調(diào)用執(zhí)行
for 的函數(shù)體。
10.下面開始學(xué)習(xí)robot,遇到不會(huì)的問題再查找書籍或網(wǎng)絡(luò)
1.scalac/scala
2.下載ant http://www.apache.org/dist/ant
3.Intellij IDEA/netbeans的scala插件/eclipse的scala插件
1.1 Array -類型參數(shù)化數(shù)組
class-類
Object-Scala不能定義靜態(tài)成員,代之定義單例對(duì)象(singleton object)
1.2 -> 左右兩邊代表一個(gè)映射關(guān)系,類似map的k-v鍵值對(duì)
1.3 trait-特質(zhì)
1.4 =>
1.5 import com.mop.sgz.core.config._
1.6 Actor 和并發(fā)
1.7_
1.8 scala中避免使用顯示的return,因?yàn)檫@樣會(huì)影響到scala推演返回類型的能力;如-
def check1() = true
def check2() : Boolean = return true
對(duì)于使用了return的方法,就需要顯示的提供返回類型,否則會(huì)有編譯錯(cuò)誤
posted on 2011-12-26 21:07
landon 閱讀(4411)
評(píng)論(0) 編輯 收藏 所屬分類:
Program