1. 程式人生 > >Scala學習整理[總結篇]

Scala學習整理[總結篇]

第二課細讀Scala

SecondWIthProgrammingInScala

結合之前的學習和感想 ,順序細讀一遍Scala的書 ,整理

  • 為了方便檢視和管理程式碼 ,書中包含的指令碼/Scala直譯器部分我都用mian函式去測試 ,方便記錄
  • 當然Scala的直譯器和指令碼執行方式也是要去嘗試一下的 ,也是很特別的

任務完成

  • 利用這段空閒時間閱讀完了Programming In Scala中文版的書 ,對Scala有了一個大致的瞭解 .中文版的書一共33章(第33是綜合章節 ,書寫一個GUI) ,都通過程式碼+註釋的方式進行了閱讀和理解

總結

  • 作為一個以Java入門的程式猿 ,Scala給我的印象非常深 .在寫Java的時候可能需要寫很大一片程式碼 ,才能描述清楚一個繼承關係/介面定義/工廠類 .使用Scala的話 ,從語法上就較少了冗餘(比如型別定義).
  • Scala提倡的函式式思想 ,val+遞迴的使用也耗費了我不少腦細胞去思考如何重構(雖然效率上需要謹慎考慮).顯然 ,這是一門”隨性的”語言 ,不同的人寫出來的程式碼是非常不一樣的.

個人看法

  • 關於語言的爭論 ,從 語言種類>2 時候就開始了 ,特別是Java是被吐槽的最多的 ,”一次編譯 ,全平臺執行”這個最初的特點也被不少人嘲笑 .現在一些新的語言在很多方面確實優於Java或是其他語言 ,但是”存在即合理”

  • Scala ,可以充分發揮程式猿自己的能力 ,你有多瞭解這門語言/瞭解JVM/瞭解JAVA/瞭解計算機結構 ,你就能重構你的程式碼 ,甚至制定你自己的編譯規則(語法糖) ,對你自己來說可以減少非常多的工作量 .

  • 不過 ,個性化的東西越多 ,當另一個人接手的時候需要花更多的時間去熟悉”你的規則”
  • 在工程開發中 ,語言只是一個工具 ,選擇一個工具 ,依賴的應該是成本(包括人力/技術/附屬產品) ,這也是Java語言不怎麼樣 ,但是Java生態圈確是主流的原因 .

不管怎麼樣 ,往廣度走 “技多不壓身” ,有充分的選擇 ;往深度走 ,”學而精” ,用命令列都能寫出作業系統.

package SecondWithProgrammingInScala

import java.awt.Font
import java.io._
import javax.swing.border._

import
scala.collection.mutable.ListBuffer import scala.swing.{BoxPanel, _} import scala.swing.event.ButtonClicked import scala.util.Random object WhereEatDinner extends SimpleSwingApplication { override def top: Frame = new MainFrame { preferredSize_=(new Dimension(500, 600)) //引數 var optionList = DinnerOption.getOptionsFromFile //控制元件 val optionArea = new BoxPanel(Orientation.Vertical) val scrollArea = new ScrollPane(optionArea) { border = new CompoundBorder(new TitledBorder("候選食堂"), new EmptyBorder(10, 10, 10, 10)) maximumSize_=(new Dimension(300, 400)) minimumSize_=(maximumSize) } showOptions val goBtn = new Button { font = new Font("微軟雅黑", 2, 20) text = "試試手氣" margin = new Insets(5, 5, 5, 5) } val addBtn = new Button { text = "新增" } val resultLable = new Label { text = "..." font = new Font("微軟雅黑", 1, 30) } //標題 title = "\"今晚去哪吃\"究極終端分期解決器v1.0" //主視窗 contents = new BoxPanel(Orientation.Vertical) { border = new EmptyBorder(30, 30, 30, 30) //上部功能 val funcElem = new BoxPanel(Orientation.Horizontal) { border = new EmptyBorder(0, 0, 20, 0) //按鈕組 val btnGroup = new BoxPanel(Orientation.Vertical) { border = new EmptyBorder(10, 10, 10, 10) //動作 listenTo(goBtn, addBtn) reactions += { case ButtonClicked(x) => if (x == addBtn) toggleAddWindow else if (x == goBtn) goSelection } contents += goBtn contents += addBtn } contents += scrollArea contents += btnGroup } val resultElem = resultLable contents += funcElem contents += resultElem } def toggleAddWindow: Unit = { dialog.open() } val dialog = new Dialog { val newFiled = new TextField { columns = 10 } val okBtn = new Button { text = "確定" } contents = new BoxPanel(Orientation.Vertical) { contents += newFiled contents += okBtn } listenTo(newFiled, okBtn) reactions += { case ButtonClicked(_) => { if (newFiled.text.isEmpty) Dialog.showConfirmation(top, "餐館名不能為空") else DinnerOption.saveOptions(new DinnerOption(optionList.size, newFiled.text)) showOptions this.close } } } def goSelection: Unit = { val random = new Random(System.currentTimeMillis()) val point = Math.abs(random.nextInt % optionList.size) val opt = optionList(point) resultLable.text = opt.name } def showOptions: Unit = { optionList.foreach(opt => optionArea.contents += new Label(opt.toString)) optionArea.repaint } } } class DinnerOption(val lineNumber: Int, val name: String) { override def toString: String = name } object DinnerOption { /** * 工廠構造方法 * * @param lineNumber * @param name * @return */ def apply(lineNumber: Int, name: String): DinnerOption = new DinnerOption(lineNumber, name) /** * 目標檔名 */ val fileName = "WhereEatDinner-Options.txt" /** * 檔案操作物件 */ val file = getFile def getOptionsFromFile: List[DinnerOption] = { val fileReader = new FileReader(file) val lineReader = new LineNumberReader(fileReader) val options = new ListBuffer[DinnerOption] var end = false while (!end) { val lineStr = lineReader.readLine() if (lineStr == null || lineStr.isEmpty) end = true else options.append(new DinnerOption(lineReader.getLineNumber, lineStr)) } fileReader.close() lineReader.close() options.toList } /** * 儲存新的Option * * @param opts */ def saveOptions(opts: DinnerOption*): Unit = { val fileWriter = new FileWriter(file, true) opts.filter(!_.name.isEmpty).foreach(x => fileWriter.append(x.name + "\n") ) fileWriter.close() } /** * 暫時沒有發現刪除 ,解決方案 ,記憶體List刪除目標 ,然後儲存重新整理剩下的 * * @param opts */ def deleteOptions(opts: DinnerOption*): Unit = { val fileWriter = new FileWriter(file) opts.filter(!_.name.isEmpty).sortWith(_.lineNumber < _.lineNumber).foreach(x => fileWriter.append(x.name + "\n") ) fileWriter.close() } /** * 獲取檔案 * * 原本想使用Option[T] ,將結果轉化為List ,可以使用for/foreach等操作 ,會自動規避None的選項 ,而不必判斷null * 但是對於獲取指定的資源(單個的) ,使用for過後還是隻會取第一個 ,與其for+get(0) ,還是判斷null來的直觀簡便 * 對於返回不止一個資源 ,並且可能為空的時候 ,使用Option * * @return */ private def getFile: File = { new File(fileName) } }