Scala學習整理[總結篇]
阿新 • • 發佈:2018-12-25
第二課細讀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)
}
}