Scala笔记学习之二

定义主函数

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}
//交互式命令行调用
HelloWorld.main(null)

Scala代码作为脚本语言

./hello.sh

#!/bin/sh
exec scala "$0" "$@"
!#
object HelloWorld extends App {
  println("Hello, world!")
}
HelloWorld.main(null)

Scala解释器命令

可以输入任意的Scala表达式
在命令行中需要分多行输入,Scala解释器在新行前面显示|

//退出
quit
//多行
val msg3=
     | "Hello world 3rd time"

定义变量

Scala的“type inference”特点 ;类型推导-自动推测类型
val 类似于Java中的final 变量 不可以重新复制
var 可以任意重新赋值

//默认会自动推测类型
val msg="Hello,World"
//也可以定义类型
val msg1:String ="Hello again,world"
var msg2="Hello,World2"
msg2="haha"

定义函数

函数在Scala语言中的地位和类是同等第一位的
每个Scala表达式都有返回结果
函数的最后一个表达式的值就可以作为函数的结果作为返回值

def max(x:Int,y:Int) : Int ={
     if (x >y) x
     else
     y
     }
max(6,7)    
def max2(x:Int,y:Int) : Int ={if (x >y) x else y} 
max2(9,7)
//无返回值 显示Unit相当于void
def greet() = println("hello,world")

while循环

scala不支持i++使用i+=1代替

var args="asdasdasd"
var i=0
while (i < args.length) {
  println (args(i))
  i+=1
}
#Scala访问数组的语法是使用()

foreach 和 for 来实现迭代

采用“函数式”风格

args.foreach(arg => println(arg))
//简写
args.foreach( println)
//for
for (arg <-args)
  println(arg)

初始化数组Array

Array可以修改内容

val greetStrings = new Array[String](3)
greetStrings(0)= "Hello"
greetStrings(1)= ","
greetStrings(2)= "world!\n"
for(i <- 0 to 2)
  print(greetStrings(i))
//简化
val greetStrings =Array("Hello",",","World\n")

Lists

Scala的Lists对象是不可修改的
List只能包含同类型的数据

val oneTwo = List(1,2)
val threeFour = List(3,4)
val oneTwoThreeFour=oneTwo ::: threeFour
println (oneTwo + " and " + threeFour + " were not mutated.")
println ("Thus, " + oneTwoThreeFour + " is a new list")

Scala 的List类 head、last、length、reverse、tail等

head、last、length、reverse、tail

oneTwoThreeFour.head list第一个元素
oneTwoThreeFour.last list最后一个元素
reverse反转length长度
oneTwoThreeFour.tail 除去第一个的其他元素

:::连接两个列表

::添加元素

//向List中添加一个元素
val oneTowThree = 1 :: 2 ::3 :: Nil
println(oneTowThree)

元组(Tuples)

Tuples可以包含不同类型的数据
返回多个结果时非常有用
对应到数学的矢量

//可以使用._索引 来访问员组的元素,元组的索引从1开始
val pair=(99,"Luftballons")
println(pair._1)
println(pair._2)

Sets和Maps

set不可修改
map可修改

var jetSet = Set ("Boeing","Airbus")
//添加元素
jetSet +="Lear"
//判断是否存在
println(jetSet.contains("Cessna"))

val romanNumeral = Map ( 1 -> "I" , 2 -> "II",
  3 -> "III", 4 -> "IV", 5 -> "V")
println (romanNumeral(4))

函数编程风格

能不用vars,尽量不用vars,能不用mutable变量,尽量不用mutable变量,能避免函数的副作用,尽量不产生副作用。

//java风格不推荐
def printArgs ( args: Array[String]) : Unit ={
    var i=0
    while (i < args.length) {
      println (args(i))
      i+=1
    }
}
//去var变量
def printArgs ( args: Array[String]) : Unit ={
    for( arg <- args)
      println(arg)
}
//更简化
def printArgs ( args: Array[String]) : Unit ={
    args.foreach(println)
}

读取文件

import scala.io.Source
def readfile( args: String) : Unit ={
if (args.length >0 ){
  for( line <- Source.fromFile(args).getLines())
    println(line.length + " " + line)
}
   else
      Console.err.println("Please enter filename")
}
readfile("/Users/yuyin/Downloads/myfile/note/test.txt")

枚举当前目录下所有文件

val filesHere = (new java.io.File(".")).listFiles
for( file <-filesHere)
  println(file)

类和对象的定义

以class 开始
缺省修饰符为public
Scala的方法的参数都是val类型,在函数体内不可以修改参数的值

class ChecksumAccumulator{
   private var sum=0
   def add(b:Byte) :Unit = sum +=b
   def checksum() : Int = ~ (sum & 0xFF) +1
}
import scala.collection.mutable.Map
class ChecksumAccumulator{
   private var sum=0
   def add(b:Byte) :Unit = sum +=b
   def checksum() : Int = ~ (sum & 0xFF) +1
}

object ChecksumAccumulator {
   private val cache = Map [String, Int] ()
   def calculate(s:String) : Int =
      if(cache.contains(s))
         cache(s)
      else {
         val acc=new ChecksumAccumulator
         for( c <- s)
            acc.add(c.toByte)
         val cs=acc.checksum()
         cache += ( s -> cs)
         cs
       }
}

println ( ChecksumAccumulator.calculate("Welcome to Scala Chinese community"))

控制语句if

//java风格
var filename="default.txt"
if(!args.isEmpty)
  filename =args(0)
//scala风格
val filename=
   if(!args.isEmpty)   args(0)
   else "default.txt"

for生成新集合

//生成Array[File]
def scalaFiles =
  for {
    file     if file.getName.endsWith(".scala")
  } yield file

用 try 表达式处理异常

val half =
  if (n % 2 == 0)
    n/2
  else
    throw new RuntimeException("n must be even")

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
try {
  val f = new FileReader("input.txt")
} catch {
  case ex: FileNotFoundException => //handle missing file
  case ex: IOException => //handle other I/O error
}

finally

通常情况下,finally块用来做些清理工作,而不应该产生结果

import java.io.FileReader
val file = new FileReader("input.txt")
try {
  //use the file
} finally {
  file.close()
}

Match 表达式

Scala的缺省匹配为“_”

val firstArg = if (args.length >0 ) args(0) else ""
firstArg match {
  case "salt" => println("pepper")
  case "chips" => println("salsa")
  case "eggs" => println("bacon")
  case _ => println("huh?")
}

使用true判断代替break与continue

var i=0
var foundIt=false
while (i < args.length && !foundIt) {
    if (!args(i).startsWith("-")) {
    if(args(i).endsWith(".scala"))
        foundIt=true
    }
    i=i+1
}

递归函数重新实现上面代码实现的查询功能:

def searchFrom(i:Int) : Int =
    if( i >= args.length) -1
    else if (args(i).startsWith("-")) searchFrom (i+1)
    else if (args(i).endsWith(".scala")) i
    else searchFrom(i+1)
val i = searchFrom(0)

filter方法用来过滤集合中的元素

val someNumbers = List ( -11, -10, - 5, 0, 5, 10)
someNumbers.filter( x => x >0)
//Scala允许使用“占位符”下划线“_”来替代一个或多个参数,只要这个参数值函数定义中只出现一次,Scala编译器可以推断出参数
someNumbers.filter(_ >0)
//print _ 来代替 println (_)
someNumbers.foreach( x => println (x))
someNumbers.foreach(println _)

部分应用函数

一个部分应用的函数指的是你在调用函数时,不指定函数所需的所有参数

//固定sum的第一和第三个参数
def sum = (_:Int) + (_ :Int) + (_ :Int)
val b = sum ( 1 , _ :Int, 3)
b(2)

闭包

引用到函数外面定义的变量

var more =1
val addMore = (x:Int) => x + more
addMore (100)
more=11
addMore (100)

可变参数

“*”来指明该参数为重复参数 变长参数

//String * 类型实际为 Array[String]
def echo (args: String *) = for (arg <- args) println(arg)
echo("x")
echo("x","ss")

_* 在传递参数时,逐个传入数组的每个元素

val arr= Array("What's","up","doc?")
echo (arr: _*)

柯里化函数(Currying)

柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

//非柯里化
def plainOldSum(x:Int,y:Int) = x + y
plainOldSum(1,2)
//柯里化
def curriedSum(x:Int)(y:Int) = x + y
curriedSum (1)(2)

Scala的类层次关系

所有的类都继承自Any,因此Scala中的对象都可以使用==、!=或equals来比较,使用##或hashCode给出hash值,使用 toString 转为字符串。
AnyVal是Scala里每个内建值类型的父类。有九个这样的值类型:Byte,Short,Char,Int,Long,Float,Double,Boolean和Unit
方法min、max、until、to和abs都定义在类scala.runtime.RichInt里,并且有一个从类Int到RichInt的隐式转换。
AnyRef是Scala里所有引用类的基类,似java.lang.Object

Trait

集合了Interface和抽象类的优点,同时又没有破坏单一继承的原则
可以使用extends或with来混合一个trait

trait Philosophical{
  def philosophize() {
    println("I consume memeory, therefor I am!")
  }
}
class Frog extends Philosophical{
  override def toString="gree"
}
val frog = new Frog
frog.philosophize
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值