[转帖]scala day5_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3273 | 回复: 0   主题: [转帖]scala day5        下一篇 
只是很无聊
注册用户
等级:中尉
经验:440
发帖:33
精华:0
注册:2013-6-18
状态:离线
发送短消息息给只是很无聊 加好友    发送短消息息给只是很无聊 发消息
发表于: IP:您无权察看 2013-6-20 13:40:17 | [全部帖] [楼主帖] 楼主

9.文件和正则表达式
9.1 读取文件的行
a:例如:

Java代码  
北京联动北方科技有限公司

  1.  import scala.io.Source  
  2. val source = Source.fromFile("myfile.txt", "UTF-8")  
  3. val lineIterator = source.getLines  



b:对每行做迭代

Java代码  
北京联动北方科技有限公司

  1. for (l <- lineIterator) process l  



c:将所有的行转化成一个数组

Java代码  
北京联动北方科技有限公司

  1. val lines = source.getLines.toArray  



d:将整个文件读成一个字符串

Java代码  
北京联动北方科技有限公司

  1. val contents = source.mkString  



e:记得关闭文件

 source.close


9.2 读取字符
a:使用source 对象

Java代码  
北京联动北方科技有限公司

  1. for (c <- source) process c  



b:在还没有读取字符的时候,就知道下一个字符,例如:

Java代码  
北京联动北方科技有限公司

  1. val source = Source.fromFile("myfile.txt", "UTF-8") 
  2. val iter = source.buffered 
  3. while (iter.hasNext) { 
  4.       if (iter.head is nice) 
  5.       process iter.next 
  6.       else 
  7.       ... 
  8. source.close() 



c:读取以空白分割的字符,将字符专程number 类型

Java代码  
北京联动北方科技有限公司

  1. val tokens = source.mkString.split("\\s+")  
  2. val numbers = for (w <- tokens) yield w.toDouble  
  3.  或者  val numbers = tokens.map(_.toDouble)、  



d:从URL 读取 或者标准输入读取文件

Java代码  
北京联动北方科技有限公司

  1. val source1 = Source.fromURL("http://horstmann.com", "UTF-8")  
  2. // Reads from the given string—useful for debugging  
  3. val source2 = Source.fromString("Hello, World!")  
  4. // Reads from standard input  

val source3 = Source.stdin


e:读取二进制文件
  使用java 的类库读取二进制文件 ,
  例如:

Java代码  
北京联动北方科技有限公司

  1.  val file = new File(filename)  
  2. val in = new FileInputStream(file)  
  3. val bytes = new Array[Byte](file.length.toInt)  
  4. in.read(bytes)  
  5. in.close()  



f:写文件
  使用java 的类库写文件

g:遍历路径
g1: 可以使用JDK1.7 nio.Files 下的 walkFileTree 方法

  例如:

Java代码  
北京联动北方科技有限公司

  1.  import java.nio.file._ 
  2. implicit def makeFileVisitor(f: (Path) => Unit) = new SimpleFileVisitor[Path] { 
  3.       override def visitFile(p: Path, attrs: attribute.BasicFileAttributes) = { 
  4.             f(p) 
  5.             FileVisitResult.CONTINUE 
  6.       } 
  7. Files.walkFileTree(dir.toPath, (f: Path) => println(f)) 



h:序列化
h1:序列化和反序列化对象方法:

Java代码  
北京联动北方科技有限公司

  1.   val fred = new Person(...)  
  2. import java.io._  
  3. val out = new ObjectOutputStream(new FileOutputStream("/tmp/test.obj"))  
  4. out.writeObject(fred)  
  5. out.close()  
  6. val in = new ObjectInputStream(new FileInputStream("/tmp/test.obj"))  
  7. val savedFred = in.readObject().asInstanceOf[Person]  



h2:scala 定义序列化对象

 @SerialVersionUID(42L) class Person extends Serializable


其中@SerialVersionUID(42L) 可以省略

h3:在scala 中collection 类都是可以序列化的e

9.9 处理控制
a:使用process 包执行shell 脚本命令
例如:

Java代码  
北京联动北方科技有限公司

  1. import sys.process._  
  2. "ls -al .." !  
  3.  ls-all .. 命令被执行 并且 显示了父目录下的所有文件 ,同时将结果输出到控制台  
  4.  sys.process 将String 隐式转换成ProcessBuider 对象   


  • ! :执行ProcessBuilder 对象。如果执行成功返回0,不成功,则返回非0 
  • !!: 执行结果作为String 返回 ,例如:val result = "ls -al .." !! 
  • #|: 将结果通过管道作为其他命令的输入,例如 "ls -al .." #| "grep sec" ! 
  • #>:将输出结果重定向到文件中  "ls -al .." #> new File("output.txt") ! 
  • #>> : 将输出结果添加到指定文件的末尾:"ls -al .." #>> new File("output.txt") ! 
  • #<: 从一个文件中重定向输入数据 "grep sec" #< new File("output.txt") ! 
  •      也可以从URL 中重定向输入数据 
  •      "grep Scala" #< new URL("http://horstmann.com/index.html") ! 
  • #&&:p #&& q 执行q 如果p 执行成功 
  • #||:p #|| q  执行q,如果p 没有执行成功 



b:构造Process 对象执行命令,使用 ! 命令执行Process 对象
例如:

Java代码  
北京联动北方科技有限公司

  1. val p = Process(cmd, new File(dirName), ("LANG", "en_US"))  
  2.  "echo 42" #| p !  



9.10 正则表达式

a: 类名: scala.util.matching.Regex
b:构造正则表达式:使用String 的 .r 方法,例如

 val numPattern = "[0-9]+".r


c:如果正则表达式中包含了 反斜杆\,双引号",则需要使用 """...""" 这种形式

  例如:

Java代码  
北京联动北方科技有限公司

  1. //// A bit easier to read than "\\s+[0-9]+\\s+".r  
  2. al wsnumwsPattern = """\s+[0-9]+\s+""".r  



d:正则表达式使用 findAllIn 方法返回一个所用匹配的Iterator

Java代码  
北京联动北方科技有限公司

  1. for (matchString <- numPattern.findAllIn("99 bottles, 98 bottles"))  
  2. process matchString  
  3.  或者转化成Array  
  4. val matches = numPattern.findAllIn("99 bottles, 98 bottles").toArray  



findAllIn: 找到全部匹配的字符串
findFirstIn:找到第一个匹配的字符串
findPrefixOf:找到一个字符串的开始是否匹配的对象
replaceFirstIn:替换第一个匹配的字符串
replaceAllIn: 替换所有匹配的字符串

9.11 正则表达式组
a:用() 包含一个子组,例如 val numitemPattern = "([0-9]+) ([a-z]+)".r
b:从多个匹配中获取组,使用如下语句:

Java代码  
北京联动北方科技有限公司

  1. for (numitemPattern(num, item) <- numitemPattern.findAllIn("99 bottles, 98 bottles"))  
  2. rocess num and item  



10.function 以及closures
10.1 本地函数local function
a:将private 函数定义 嵌套在 主调用方法中,对外界屏蔽了实现细节
  例如:

Java代码  
北京联动北方科技有限公司

  1.  def processFile(filename: String, width: Int) { 
  2.       def processLine(filename: String, 
  3.       width: Int, line: String) { 
  4.             if (line.length > width) 
  5.             println(filename +": "+ line) 
  6.       } 
  7.       val source = Source.fromFile(filename) 
  8.       for (line <- source.getLines()) { 
  9.             processLine(filename, width, line) 
  10.       } 



b:本地函数可以访问 外面包围函数的参数

10.2 first-class function


a:function literal 语法

 (函数参数1,函数参数2)=>{函数体}
  例如:
(x:Int,y:Int)=>x+y
b:function literal 被编译成一个类,在运行时期被实例化,称为function value
c:function literal 和function value 之间的区别是:
   literal  存在于源码中,而value 存在与运行时期的object
d:function value 由于在运行时期是一个object,因此可以作为变量赋值给对象,
之后可以使用函数调用的方法 functionanme(param) 调用该函数
  例如:

Java代码  
北京联动北方科技有限公司

  1.  scala> var increase = (x: Int) => x + 1  
  2. increase: (Int) => Int = <function1>  
  3. scala> increase(10)  
  4. res0: Int = 11  



e:  在function literal 中,函数体有多个语句,则需要用{} 构造语句块,
  其中每个语句都单独为一行
  例如:

Java代码  
北京联动北方科技有限公司

  1. scala> increase = (x: Int) => { 
  2.       println("We") 
  3.       println("are") 
  4.       println("here!") 
  5.       x + 1 
  6. increase: (Int) => Int = <function1> 
  7. scala> increase(10) 
  8. We 
  9. are 
  10. here! 
  11. res2: Int = 11 



10.3 function literal 的简写形式
a:去掉参数类型 :如果参数类型能够根据调用者推断出来,则可以去掉参数的类型
b:去掉():如果去掉了参数类型,则可以去掉()
例如:

Java代码  
北京联动北方科技有限公司

  1. scala> someNumbers.filter(x => x > 0)  
  2. es6: List[Int] = List(5, 10)  



c: 使用_ 下划线做单个参数的占位符号
例如:

Java代码  
北京联动北方科技有限公司

  1. someNumbers.filter(_ > 0)  
  2. val f = (_: Int) + (_: Int)  



10.4 Partially applied functions 部分应用的函数
a:部分应用函数 表达式 使用方法
functionName _
例如:

Java代码  
北京联动北方科技有限公司

  1. print _    
  2.        sum _  



b:例如:

Java代码  
北京联动北方科技有限公司

  1. scala> val a = sum _  
  2. a: (Int, Int, Int) => Int = <function3>  



生成一个a引用指向新的函数值,其实上述方法调用相当与

Java代码  
北京联动北方科技有限公司

  1. scala> a(1, 2, 3)  
  2. res11: Int = 6  
  3. scala> a.apply(1, 2, 3)  
  4. res12: Int = 6  



c:functionName _  可以实现 包裹方法和功能function嵌套
d:对原函数的所有参数 只是提供部分参数 并不提供全部的参数 也是应用的一种情况
例如:

Java代码  
北京联动北方科技有限公司

  1. scala> val b = sum(1, _: Int, 3)  
  2. b: (Int) => Int = <function1>  
  3.  scala编译器会为产生一个其中apply方法只是携带一个参数的 函数类一个   



下面就是一些调用例子:

Java代码  
北京联动北方科技有限公司

  1. scala> b(2)  
  2. res13: Int = 6  
  3. scala> b(5)  
  4. res14: Int = 9  



d: 如果调用点指定要求的类型是 函数类型时,如果要为 该参数 传入 functionName _ ,其中_ 可以省略

10.5 定义closures
a:定义closures:
  在运行时根据function literal 创造的function value ,称为closures
b:

Java代码  
北京联动北方科技有限公司

  1. scala> var more = 1  
  2. more: Int = 1  
  3. scala> val addMore = (x: Int) => x + more  
  4. addMore: (Int) => Int = <function1>  
  5. scala> addMore(10)  
  6. res17: Int = 11  



def makeIncreaser(more: Int) = (x: Int) => x + more


c:closures 能够捕获变量的本身,而不是变量指向的引用值。因此当外面的变量值变化时,则closures 也能够捕获到这个变化
d:同理 在closures 中改变的变量值 也会被外面的变量给捕获到,例如:

Java代码  
北京联动北方科技有限公司

  1. scala> val someNumbers = List(-11, -10, -5, 0, 5, 10)  
  2. someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)  
  3. scala> var sum = 0  
  4. sum: Int = 0  
  5. scala> someNumbers.foreach(sum +=  
  6. _)  
  7. scala> sum  
  8. res20: Int = -11  



10.6 函数调用的特殊形式

a:可重复的参数
参数类型后面加上字符*,就表示可重复的参数,例如:

Java代码  
北京联动北方科技有限公司

  1.  def echo(args: String*) =  
  2.  for (arg <- args) println(arg)  
  3. scala> echo()  
  4. scala> echo("one")  
  5. one  
  6. scala> echo("hello", "world!")  
  7. hello  
  8. world!  



技术上 String* 相当与Array[String] ,单数如果给 echo 传递 Array 对象,则会报类型的编译错误,因此对于Array 可以修改为:

echo(arr: _*)


b:带名字的参数以及具有默认值的参数
带名字的参数,
  参数名=参数值,该种类型允许传递的参数可以不一参数定义的顺序进行传递
例如:

Java代码  
北京联动北方科技有限公司

  1. scala> def speed(distance: Float, time: Float): Float =  
  2. distance / time  
  3. speed: (distance: Float,time: Float)Float  
  4. scala> speed(100, 10)  
  5. res28: Float = 10.0  
  6. scala> speed(distance = 100, time = 10)  
  7. res29: Float = 10.0  
  8. scala> speed(time = 10, distance = 100)  
  9. res30: Float = 10.0  



具有默认值的参数: 则允许不传递参数,而使用默认值
例如:

Java代码  
北京联动北方科技有限公司

  1. def printTime(out: java.io.PrintStream = Console.out) =  
  2. out.println("time = "+ System.currentTimeMillis())  




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论