使用Scala


1. 凈資產應用實例

我們要構建這樣一個應用,它會取回一份列表,其中包括用戶持有的股票的代碼以及股份,並告知他們在當前日期為止的這些投資的總價。這包含了幾件事:獲取用戶輸入、讀文件、解析數據、寫文件、從Web獲取數據、把信息顯示給用戶。

我們會先開發一個控制台應用。然后,把它轉換成Swing應用。一次一步,沿着這條路重構應用。

2. 獲取用戶輸入

Scala的Console類可以從命令行獲取用戶輸入。

下面的代碼將信息讀入內存:

package com.cn.gao
//獲取用戶輸入
class ConsoleInput {
    print("Please enter a tiker symbol:")
    val symbol = Console.readLine
    //val symbol = readLine  //This will work too
    println("OK, got it, you own " + symbol)
}
//object ConsoleInput extends App{
//  new ConsoleInput()
//}

程序運行結果如下:

Please enter a tiker symbol:AAPL
OK, got it, you own AAPL

3. 讀寫文件

用java.io.File可以做這件事。下面是個寫文件的例子:

package com.cn.gao
import java.io._
//寫文件
class WriteToFile {
    val writer = new PrintWriter(new File("D:\\symbols.txt"))
    writer write "AAPL"
    writer.close()
}

//object WriteToFile extends App{
//  new WriteToFile()
//}

上面的這段代碼將股票代碼"AAPL"寫入到文件D:\\symbols.txt里。文件內容如下:

AAPL

讀文件寫真的很簡單。Scala的Source類及其伴生對象就是為這種目的而存在的。為了演示,我們寫了一個Scala腳本:

 

package com.cn.gao
import scala.io.Source
/**
 * 讀文件
 */
class ReadingFile {
    println("請輸入你要讀出的文件完整路徑:")
    val name = readLine //或者Console.readLine
    Source.fromFile(name).foreach(print)
}

object ReadingFile extends App{
  new ReadingFile()
}

在上面的代碼里,讀取了相應的文件,打印出其內容如下所示:

請輸入你要讀出的文件完整路徑:
D://data.txt
linux的特點
1.免費的/開源
2.支持多線程./多用戶的
3.安全性好
4.對內存和文件管理優越.



linux最小只需要4m->嵌入式開發
samba服務器用於和windows進行交互
從事網絡開發必讀三本書:
    TCP/ip詳解,協議
    實現
    TCP事務協議 http nntp和UNIX域協議
tracert    目標ip/域名    查看經過的網關數目(追蹤路由)
ping 目標ip         測試兩個ip是否暢通
1.在windows中查看ip情況的命令是ipconfig
2.在linux/unix下查看ip命令是ifconfig
        linux網絡環境配置
第一種方法:
  (1)用root身份登錄,運行setup命令進入到text mode setup utiliy對
網絡進行配置。這里可以進行ip,子網掩碼,默認網關,dns的設置。
  (2)這時網卡配置沒有生效,運行/etc/rc.d/init.d/network restart命
令我們剛才作的設置生效
第二種方法:
  (1)ifconfig eth0 x.x.x.x對網卡進行設置
  (2)ifconfig eth0 network x.x.x.x對子網掩碼設置
   對廣播地址和dns使用默認的。
   注意:這樣配置網絡將會立即生效,但是是臨時生效。
第三種方法:
  (1)修改/etc/sysconfig/network-scripts/ifconfig-eth0這個文件里各個
屬性可以修改,包括ip,子網掩碼,廣播地址,默認網關。
  (2)這時網卡的配置沒有生效,運行/etc/rc.d/init.d/network restart
命令我們剛才作的設置才生效。
這種方法是最底層的修改方法
         samba的安裝步驟
    a.看看是否已經安裝了samba
    rpm -q samba
    b.如有,如何卸載
     rpm -e samba
    rpm -e --nodeps samba
    




http://blog.csdn.net/eric491179912/article/details/6179908

Source類是一個輸入流上的Iterator。Source的伴生對象有幾個便利方法去讀文件、輸入流、字符串甚至是URL,稍后會看到。foreach()方法一次讀取一個字符(輸入是緩沖的,不必擔心性能)。如果需要一次讀一行,那就用getLines()方法。

很快我們就會從Web讀信息了。因此,討論Source時,讓我們看看它的fromURL()方法。這個方法可以讀取網站、web服務或是任何可以用URL指向東西的內容。下面是個例子,讀入Scala文檔站點,確定文檔相關的Scala版本號:

 

package com.cn.gao
import scala.io.Source
import java.net.URL
/**
 * 從Web讀取信息
 */
class ReadingURL {
    val source = Source.fromURL(
        new URL("http://www.scala-lang.org/docu/files/api/index.html"))
        
        println(source.getLine(3))
        val content = source.mkString
        val VersionRegEx = """[\D\S]+scaladoc\s+\(version\s+(.+)\)[\D\S]+""".r
        content match {
      case VersionRegEx(version) => println("Scala doc for version: " + version)
    }
}

object ReadingURL extends App{
  new ReadingURL()
}

 上面的代碼調用fromURL()獲得Source實例,這樣,就可以從URL讀取內容,然后進行迭代。將3傳入getLine()方法,讀取第三行。使用這個方法必須小心謹慎。索引值從1開始,而不是0,所以,第一行實際上是用索引1引用的。

 4. XML,作為一等公民

Scala把XML當作一等公民。因此,不必把XML文檔嵌入字符串,直接放入代碼即可,就像放一個int或Double值一樣。看個例子:

 

package com.cn.gao
import scala.xml._ 
class UseXML {
    val xmlFragment = 
      <symbols>
            <symbol ticker="AAPL"><units>200</units></symbol>
            <symbol ticker="IBM"><units>215</units></symbol>
      </symbols>
      println(xmlFragment)
      println(xmlFragment.getClass())
}

object UseXML extends App {
  new UseXML()
}

這里創建了一個val,叫做xmlFragment,直接把一些XML樣例內容賦給它。Scala解析了XML的內容,欣然創建了一個scala.xml.Elem的實例,輸出如下:

<symbols>
            <symbol ticker="AAPL"><units>200</units></symbol>
            <symbol ticker="IBM"><units>215</units></symbol>
      </symbols>
class scala.xml.Elem

Scala的scala.xml包提供了一些類,用以讀取、解析、創建和存儲XML文檔。

你或許用過XPath,它提供了一種強大的查詢XML文檔的方式。Scala提供了一種類似XPath的查詢能力,但略有差異。對於輔助解析和提取的方法,Scala不用斜線(/和//)查詢,而用反斜線(\和\\)。這個差異是必需的,因為Scala遵循Java的傳統,使用兩個斜線表示注釋。這樣,我們看一下如何解析手頭上的這個XML片段。

首先,要獲取symbol這個元素。為了做到這一點,可以使用類似XPath的查詢,如下:

package com.cn.gao
import scala.xml._ 
class UseXML {
    val xmlFragment = 
      <symbols>
            <symbol ticker="AAPL"><units>200</units></symbol>
            <symbol ticker="IBM"><units>215</units></symbol>
      </symbols>
//      println(xmlFragment)
//      println(xmlFragment.getClass())
  var symbolNodes = xmlFragment \ "symbol"
  println(symbolNodes.mkString("\n"))
  println(symbolNodes.getClass())
}

object UseXML extends App {
  new UseXML()
}

上面的代碼的輸出如下:

<symbol ticker="AAPL"><units>200</units></symbol>
<symbol ticker="IBM"><units>215</units></symbol>
class scala.xml.NodeSeq$$anon$1

這里調用了XML元素的\()方法,讓它找到所有symbol元素。它會返回一個scala.xml.NodeSeq的實例,表示XML節點的集合。

\()方法只會找出是目標元素(本例子里是symbols元素)直接后代的元素。如果想從目標元素出發,搜出層次結構里所有的元素,就要用\\()方法,如下所示。此外,用text()方法可以獲取元素里的文本節點。

 

package com.cn.gao
import scala.xml._ 
class UseXML {
    val xmlFragment = 
      <symbols>
            <symbol ticker="AAPL"><units>200</units></symbol>
            <symbol ticker="IBM"><units>215</units></symbol>
      </symbols>
//      println(xmlFragment)
//      println(xmlFragment.getClass())
      
//  var symbolNodes = xmlFragment \ "symbol"
//  println(symbolNodes.mkString("\n"))
//  println(symbolNodes.getClass())
      
    var unitsNodes = xmlFragment \\ "units"
    println(unitsNodes.mkString("\n"))
    println(unitsNodes.getClass())
    println(unitsNodes(0).text)
}

object UseXML extends App {
  new UseXML()
}

上面的代碼的輸出如下:

<units>200</units>
<units>215</units>
class scala.xml.NodeSeq$$anon$1
200

在上面的例子里,使用了text()方法去獲取文本節點。模式匹配也可以獲取文本值以及其他內容。如果想瀏覽XML文檔的結構,\()和\\()兩個方法很有用。不過,如果想匹配XML文檔任意位置的內容,模式匹配會顯得更有用。

 Scala也將模式匹配擴展到了XML片段的匹配上,如下所示:

package com.cn.gao
import scala.xml._ 
class UseXML {
    val xmlFragment = 
      <symbols>
            <symbol ticker="AAPL"><units>200</units></symbol>
            <symbol ticker="IBM"><units>215</units></symbol>
      </symbols>
//      println(xmlFragment)
//      println(xmlFragment.getClass())
      
//  var symbolNodes = xmlFragment \ "symbol"
//  println(symbolNodes.mkString("\n"))
//  println(symbolNodes.getClass())
      
    var unitsNodes = xmlFragment \\ "units"
//    println(unitsNodes.mkString("\n"))
//    println(unitsNodes.getClass())
//    println(unitsNodes(0).text)
    
    unitsNodes(0) match {
      case <units>{numberOfUnits}</units> => println("Units: " + numberOfUnits)
    }
}

object UseXML extends App {
  new UseXML()
}

上面代碼的輸出如下:

Units: 200

這里,取出第一個units元素,讓Scala提取出文本值200。在case語句里,我們對感興趣的片段進行匹配,用一個變量numberOfUnits,當做這個元素的文本內容的占位符。

這樣就可以獲取到一支股票的股份了。不過還是有兩個問題。前一種方式只對內容剛好匹配case里表達式的情況起作用;也就是說,units元素只能包含一個內容項或是一個子元素。如果它包含的是子元素和文本內容的混合體,上面的匹配就會失敗。而且這里想得到的是所有股票的股份,而不是第一個。運用_*,就可以讓Scala抓出所有的內容(元素和文本),如下所示:

package com.cn.gao
import scala.xml._ 
class UseXML {
    val xmlFragment = 
      <symbols>
            <symbol ticker="AAPL"><units>200</units></symbol>
            <symbol ticker="IBM"><units>215</units></symbol>
      </symbols>
//      println(xmlFragment)
//      println(xmlFragment.getClass())
      
//  var symbolNodes = xmlFragment \ "symbol"
//  println(symbolNodes.mkString("\n"))
//  println(symbolNodes.getClass())
      
    var unitsNodes = xmlFragment \\ "units"
//    println(unitsNodes.mkString("\n"))
//    println(unitsNodes.getClass())
//    println(unitsNodes(0).text)
    
//    unitsNodes(0) match {
//      case <units>{numberOfUnits}</units> => println("Units: " + numberOfUnits)
//    }
    
    println("Ticker\tUnits")
    xmlFragment match {
      case <symbols>{symbolNodes @ _*}</symbols> =>
        for(symbolNode @ <symbol>{_*}</symbol> <- symbolNodes){
          println("%-7s %s".format(
              symbolNode \ "@ticker", (symbolNode \ "units").text)) //用@前綴表示屬性查詢
        }
    }
}

object UseXML extends App {
  new UseXML()
}

上面代碼的輸出如下:

Ticker    Units
AAPL    200
IBM     215

5. 讀寫XML

只有將XML讀入內存,才能夠進行解析。下一步,我們來了解如何將XML文檔加載到程序里,如何把內存里的文檔存入文件。作為例子,我們會加載一個包含股票代碼和股份的文件,對股份加1,然后將更新的內容存回到另一個XML文件里。我們先來處理加載文件的這一步。

這是要加載的樣例文件stocks.xml:

<symbols>
    <symbol ticker="AAPL"><units>200</units></symbol>
    <symbol ticker="ADBE"><units>125</units></symbol>
    <symbol ticker="ALU"><units>150</units></symbol>
    <symbol ticker="AMD"><units>150</units></symbol>
    <symbol ticker="CSCO"><units>250</units></symbol>
    <symbol ticker="HPQ"><units>225</units></symbol>
    <symbol ticker="IBM"><units>215</units></symbol>
    <symbol ticker="INTC"><units>160</units></symbol>
    <symbol ticker="MSFT"><units>190</units></symbol>
    <symbol ticker="NSM"><units>200</units></symbol>
    <symbol ticker="ORCL"><units>200</units></symbol>
    <symbol ticker="SYMC"><units>230</units></symbol>
    <symbol ticker="TXN"><units>190</units></symbol>
    <symbol ticker="VRSN"><units>200</units></symbol>
    <symbol ticker="XRX"><units>240</units></symbol>
</symbols>

scala.xml的XML單例對象的load()方法可以輔助加載文件,如下所示:

package com.cn.gao
import scala.xml._
class ReadWriteXML {
    val stocksAndUnits = XML.load("D:\\stocks.xml")
    println(stocksAndUnits.getClass())
    println("Loaded file has " + (stocksAndUnits \\ "symbol").size +
        " symbol elements")
}

object ReadWriteXML extends App {
  new ReadWriteXML()
}

從下面的輸出可以看出,load()返回的是一個scala.xml.Elem實例。此外還可以看到,加載的文件(stocks.xml)包含15個symbol元素。

class scala.xml.Elem
Loaded file has 15 symbol elements

我們已經知道如何解析這個文檔的內容,下面將股票代碼以及其對應的股份存到Map里。下面這段代碼做的就是這件事:

package com.cn.gao
import scala.collection.mutable._
import scala.xml._
class ReadWriteXML {
    val stocksAndUnits = XML.load("D:\\stocks.xml")
//    println(stocksAndUnits.getClass())
//    println("Loaded file has " + (stocksAndUnits \\ "symbol").size +
//        " symbol elements")
    
    val stocksAndUnitsMap =
      (Map[String, Int]() /: (stocksAndUnits \ "symbol")) {(map, symbolNode) =>
        val ticker = (symbolNode \ "@ticker").toString
        val units = (symbolNode \ "units").text.toInt
        map(ticker) = units    //Creates and returns a new Map
        }
    println("Number of symbol elements found is " + stocksAndUnitsMap.size)
}

object ReadWriteXML extends App {
  new ReadWriteXML()
}

最后一步,增加股份值,創建數據的XML表示,存入文件。

package com.cn.gao
import scala.collection.mutable._
import scala.xml._
class ReadWriteXML {
    val stocksAndUnits = XML.load("D:\\stocks.xml")
//    println(stocksAndUnits.getClass())
//    println("Loaded file has " + (stocksAndUnits \\ "symbol").size +
//        " symbol elements")
    
    val stocksAndUnitsMap =
      (Map[String, Int]() /: (stocksAndUnits \ "symbol")) {(map, symbolNode) =>
        val ticker = (symbolNode \ "@ticker").toString
        val units = (symbolNode \ "units").text.toInt
        map(ticker) = units    //Creates and returns a new Map
        }
    println("Number of symbol elements found is " + stocksAndUnitsMap.size)
    
    val updatedStocksAndUnitsXML = 
      <symbols>
        { stocksAndUnitsMap.map{ updateUnitsAndCreateXML }}
      </symbols>
    
    def updateUnitsAndCreateXML(element : (String, Int))= {
      val (ticker, units) = element
      <symbol ticker={ticker}>
          <units>{units + 1}</units>
      </symbol>
    }
    
    XML save ("D:\\stocks2.xml", updatedStocksAndUnitsXML)
    println("The saved file contains " + 
        (XML.load("D:\\stocks2.xml") \\ "symbol").size = " symbol elements")
}

object ReadWriteXML extends App {
  new ReadWriteXML()
}

 6. GUI使用示例

package com.cn.gao
import scala.swing._
import event._
object SampleGUI extends SimpleSwingApplication {
    def top = new MainFrame {
      title = "A Sample Scala Swing GUI"
      
      val label = new Label {text = "------------"}
      val button = new Button { text = "Click me"}
      
      contents = new FlowPanel {
        contents += label
        contents += button
      }
      
      listenTo(button)
      
      reactions += {
        case ButtonClicked(button) =>
          label.text = "You clicked!"
      }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM