1. 程式人生 > >Scala中Method的操作

Scala中Method的操作

scala中的method簡單使用:

建立一個MethodScala.scala的指令碼,程式碼如下:

//scala中的方法
import scala.io.Source
object MethodScala{

  //定義一個方法
  def processFile(fileName: String,width: Int): Unit ={
    val source = Source.fromFile(fileName,"UTF-8")
    for(line <- source.getLines())
      processLine(fileName,width,line)
  }

  private def processLine(fileName: String,width: Int, line: String): Unit ={
    if(line.length > width)
      println(fileName + ": " + line)
  }

  //一般在程式中儘量將方法精細化,更容易理解。這樣做的話一個物件裡面會有多個方法,這些方法都會影響程式的名稱空間。
  //在java中可以用private解決,scala中也可以使用私有方法解決。scala提供了另一個機制就是可以在物件函式中定義另外的函式
  def locationFunction(fileName: String,width: Int): Unit = {
    //本地方法
    def locationFunctionLine(fileName: String,width: Int,line: String){
      if(line.length > width)
        println(fileName + ": " + line)
    }
    //讀取檔案資訊
    var source = Source.fromFile(fileName,"UTF-8")
    for(line <- source.getLines)
      locationFunctionLine(fileName,width,line)
  }

}

之後建立一個程式的主入口指令碼,MethodRun.scala,程式碼如下:


object MethodRun{

  def main(args: Array[String]){
    val width = args(0).toInt
    for(arg <- args.drop(1))  //drop 選擇除前n個元素之外的所有元素。
      MethodScala.processFile(arg,width)

    //本地方法的使用
    for(arg <- args.drop(1))
      MethodScala.locationFunction(arg,width)

    //函式在scala中是一等公民
    var increase = (x : Int) => x + 1
    println("increase(10):" + increase(10))
    //我們可以給函式新增處理程式碼塊
    var increaseBlock = (x : Int) => {
      println("We")
      println("are")
      println("Here!")
      x + 1
    }
    println("increaseBlock(10):" + increaseBlock(10))

    //list集合的遍歷和過濾
    val someNumbers = List(10,2,-12,3,0,-56)
    someNumbers.foreach((x: Int) => println(x))
    //過濾
    println(someNumbers.filter((x: Int) => x > 0))
    //佔位符語法:將list中的每一個元素與_進行替換,進行和0進行比較
    println(someNumbers.filter(_ > 0))
    //定義一個方法,使用_進行操作
    val functions = (_: Int) + (_: Int)
    println("functions = (_: Int) + (_: Int):" + functions(1,4))
    //我們列印下面的list中的元素的時候,也可以使用_佔位符
    someNumbers.foreach(print _)  //等同於someNumbers.foreach(x =>print(x))

    def sum(a: Int,b: Int,c: Int) = a + b + c
    val result = sum _
    println("sum funtion:" + sum(1,2,3))
    println("result _:" + result(1,2,3))
    println("result apply:" + result.apply(1,2,3)) //這裡的apply是和_等價的,這個是scala編譯器轉換為sum _
    val result2 = sum(1, _: Int,3)
    println("result2 _:" + result2(1))

    //函式的閉包:函式值(物件)是在執行時由這個函式文字建立的,稱為閉包
    val closeVal = 3;
    someNumbers.foreach((x : Int) => println("x+closeVal:" + (x + closeVal)))

    //Scala允許您指出函式的最後一個引數可能是重複的。
    //這允許客戶端將可變長度的引數列表傳遞給函式。若要表示重複引數,請在引數型別後面加星號
    def echo(args: String*) =
      for(arg <- args) println(arg)
    //邊長引數 這裡和java中的可變長引數使用差不多 String ... args
    echo("Hello","world")  //這個方法不能傳遞一個Array[String],如果需要傳遞一個Array,改為如下方式
    echo(args: _*)

    //重新命名引數
    def namedParam(total: Float,time: Float): Float =
      total/time

    //呼叫引數的方式
    println(namedParam(100,10))
    println(namedParam(total = 100,time = 10))
    println(namedParam(time = 10,total = 100))
    //改相關引數設定預設值
    //Scala允許為函式引數指定預設值。
    //可以從函式呼叫中選擇性地省略此類引數的引數,在這種情況下,相應的引數將用預設值填充
    def printTime(out: java.io.PrintStream = (Console.out)) =
      out.println("time = " + System.currentTimeMillis())

    printTime()  //如果你這個引數不傳的話,預設的out將會是Console.out
    printTime(Console.err)

    def printTime2(out: java.io.PrintStream = (Console.out),param2: Int = 3) =
      out.println("time = " + System.currentTimeMillis() + " param2: " + param2)

    printTime2()  //不傳引數將會使用預設的引數
    printTime2(Console.err)
    printTime2(param2 = 4)

    //遞迴的使用:遞迴就是方法自己呼叫自己
    //尾部呼叫優化為近似編譯的程式碼本質上與為近似迴圈編譯的程式碼相同
    //下面程式碼不是尾部遞迴,因為它在遞迴呼叫之後執行遞增操作
    def boom(x : Int) : Int =
      if(x == 0) throw new Exception("Boom!")
      else boom(x -1) + 1

    boom(3)
    //利用編譯命令scalac 後面新增-g:notailcalls關閉
    def bang(x : Int) : Int =
      if(x == 0) throw new Exception("Bang!")
      else bang(x -1)

    bang(4)

    def nestedFun(x : Int){
      if(x != 0){
        println(x);
        funValue(x - 1)
      }
    }
    val funValue = nestedFun _
  }
}

後面將會進行相應的補充。。。