从零学scala文件和正则表达式特质

Posted wuxiaolong4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零学scala文件和正则表达式特质相关的知识,希望对你有一定的参考价值。

一:文件和正则表达式

读取行

        import scala.io.Source
        val lines = Source.fromFile("D://report_data2.txt","UTF-8").getLines()   
        for( i <- lines) println(i)//遍历每一行的数据

        val array = Source.fromFile("D://report_data2.txt","UTF-8").toArray                    //将读取到的数据作为一个数组
        val mkString = Source.fromFile("D://report_data2.txt","UTF-8").mkString("|")     //将读取到的数据作为一个字符串

读取字符

        import scala.io.Source
        val lines = Source.fromFile("D://report_data2.txt","UTF-8").buffered //每次只读取一个字符,个人感觉有点浪费资源了,可以一次读取更多的
        for( i <- lines) println(i)

读取词法单元和数字

        import scala.io.Source
        val lines = Source.fromFile("D://report_data2.txt","UTF-8").mkString.split("\|")     //直接按照|切割字符串
        for( i <- lines) println(i)

        import scala.io.Source
        val lines = Source.fromFile("D://report_data2.txt","UTF-8").mkString.split("\|")
        lines.map { x => x.toInt }.map { x => println(x)}                                                     //将数据转换为Int类型

从URL或其他源读取

        import scala.io.Source
        val urlLines = Source.fromURL("https://www.baidu.com/index.php","UTF-8").getLines()     //从URL读取
        for(i <- urlLines) println(i)

        val fromString = Source.fromString("https://www.baidu.com/index.php") //从字符串读取
        val fromStdin = Source.stdin

读取二进制文件

        import scala.io.Source
        import java.io.File
        import java.io.FileInputStream
        val file = new File("D://report_data2.txt")                       //不只是可以读取txt文件,还可以读取excel等
        val in = new FileInputStream(file)
        val bytes = new Array[Byte](file.length().toInt) 
        while(in.read(bytes) != -1) println(new String(bytes))     //将读取到的数据生成字符串打印出来
        in.close() ;

写入文本文件

        import java.io.PrintWriter
        val file = new PrintWriter("D://report_data2.txt")   //其实还是java 的用法
        file.println("aa")
        file.println("bb")
        file.println("cc")
        file.println("dd")
        file.close()

访问目录

scala遍历目录使用的还是java的file功能,只不过使用scala语法更简单明了了

        import java.io.File

        object FastLearnScala{
                def readDir(file:File):Unit = { //打印出来目录下面所有的文件
                        for(i <- file.listFiles()){
                                if(i.isFile()) println(i.getName) else readDir(i)
                        }
                }
                def main(args: Array[String]): Unit = {
                        val file = new File("D://TGP")
                        readDir(file)
                }
        }

序列化

        class Persion extends Serializable{
                val name = Array("name1","name2","name3")   //Array对象已经序列化过了,所以可以直接使用
                val age = Array("age1","age2","age3")
        }
        object FastLearnScala{

                def main(args: Array[String]): Unit = {//java语法占大部分,如果java比较熟悉看起来应该没有什么困难
                        val persion = new Persion
                        import java.io.File
                        import java.io.{ObjectOutputStream,ObjectInputStream}
                        import java.io.{FileOutputStream,FileInputStream}
                        val oos = new ObjectOutputStream(new FileOutputStream("D://report_data2.txt"))
                        oos.writeObject(persion);oos.flush();oos.close();
                        val ois = new ObjectInputStream(new FileInputStream("D://report_data2.txt"))
                        val readObject = ois.readObject().asInstanceOf[Persion]
                        println(readObject.age.mkString("|") + "&" + readObject.name.mkString("|"))
                }
        }

进程控制

        import sys.process._
        "ls -a" !//打印到控制台
        "ls -a" !!//将结果以字符串的形式返回
        "ls -a" #| "grep aa"! //管道命令的使用
        import java.io.File
        "ls -a" #> new File("1.txt") ! //输出的重定向,覆盖式操作

正则表达式

        val numPatter = "[0-9]*".r //基本的表达式
        val wsnumPatter = """s[0-9]+s""".r //如果表达式中含有的时候建议使用"""字符串"""
        for(string<- wsnumPatter.findAllIn("aaaa 1111 bbbb 2222 cccc 3333"))
        println(string)
        println("1235576879".matches(numPatter.toString())) //其实这种才是最常用的

正则表达式组

        val wsnumPatter = "([0-9]+) ([a-z]+)".r //基本的表达式
        for(wsnumPatter(num,str)<- wsnumPatter.findAllIn("1111 aaaa, 2222 bbbb, 3333 cccc"))
                println(num+"|"+str)

二:特质

为什么没有多重继承

 简单说就是一个class同时继承了多了class,当你继承的class中有多个相同名称的函数或者变量的时候,你不知道该使用哪一个。

java的解决方法是:一个类只能extends一个类,但是可以实现多个接口,接口中不不能包含抽象字段的,但是可以包含抽象方法

scala的解决方法是:提供了特质这个性质:特质可以同时有抽象方法和具体方法(相当于abstract class),而且一个类可以实现多个特质

当做接口使用的特质

        trait logger{
                def log(msg:String){}
        }
        trait logger1{
                def log(msg:String){}
        }
        class Consolelogger extends logger with logger1{ //使用extends关键字,多个的时候后跟with
                override def log(msg:String){println(msg)}
        }

scala是基于JVM运行的所以,他的特性和JAVA一样。只能extends一个class,但是可以继承多个trait

带具体实现的特质

        trait logger{
                def log(msg:String){}
        }
        trait logger1{
                def console(msg:String){println("logger1:" + msg)}
        }
                class Consolelogger extends logger with logger1{ //使用extends关键字,多个的时候后跟with
                override def log(msg:String){println(msg)}
        }

        object FastLearnScala{

                def main(args: Array[String]): Unit = {
                        val consolelogger = new Consolelogger
                        consolelogger.console("aa")
                }
        }

  //其实和abstract class的用法是一致的

带有特质的对象

        trait logged{
                def log(msg:String){println("logged:"+msg)}
        }
        trait Consolelogger { //trait还是可以有实现方法的
                def log(msg:String){println("Consolelogger:"+msg)}
        }

叠加在一起的特质

 

        trait logged{
                def log(msg:String){println("logged:"+msg)}
        }
        trait Consolelogger { //使用extends关键字,多个的时候后跟with
                def log(msg:String){println("Consolelogger:"+msg)}
        }
        class Account extends logged with Consolelogger{
                override def log(msg:String){super.log(msg)}
        }

  //继承多了类的时候,以最右边实现为主

在特质中写抽象方法

        trait logged{
                def log(msg:String){println("logged:"+msg)}
        }
        class Account extends logged {
                override def log(msg:String){println("Account:"+msg)}//和平时一样的,就是加一个override 方法
        }

当做富接口使用的特质

        trait logged{
                def log(msg:String){}
                def info(msg:String){println("logged info:"+msg)}
                def warn(msg:String){println("logged warn:"+msg)}
                def error(msg:String){println("logged error:"+msg)}
        }
        class Account extends logged {

        }
        object FastLearnScala{

                def main(args: Array[String]): Unit = {
                        val consolelogger = new Account
                        consolelogger.error("aa")
                }
        }

  //scala中有很多这种抽象方法和具体方法一起使用的场景

特质中的具体字段

        trait Logged{
                val logged = "logged"
        }
        class Account extends Logged {
                val account = "Account"
        }
        object FastLearnScala{
                def main(args: Array[String]): Unit = {
                        val consolelogger = new Account
                        println(consolelogger.logged)
                        println(consolelogger.account)
                }
        }

        //子类会将父类所有的字段都继承过来,相同名称的会override方法覆盖

特质中的抽象字段

        trait Logged{
                val logged:String
        }
        class Account extends Logged {
                val logged = "Account"
        }

        //父类中未初始化的字段在子类中都必须复写

特质构造顺序

        trait Logged{
                val logged:String = "Logged"
        }
        trait Account extends Logged{
                override val logged:String = "Account"
        }
        trait FileLogger{
                val logged:String = "FileLogger"
        }
        trait ShortLogger extends Logged{
                override val logged:String = "ShortLogger"
        }
        class SavingsAccount extends Account with FileLogger with ShortLogger{
                override val logged = "Account"
        }
        object FastLearnScala{

                def main(args: Array[String]): Unit = {
                        val consolelogger = new SavingsAccount
                        println(consolelogger.logged)
                }
        }

        //初始化顺序为:Logged(Account父类)-->>Account-->>FileLogger -->>ShortLogger(Logged已经初始化了)

        //基本和JAVA是一致的  

初始化特质中的字段

        trait Logged{
                val number = 10
        }
        class Account extends Logged{
                override val number = 20
                val array = new Array[String](number)
        }

        //这个例子上面已经有了,就是初始化数组长度的时候,其实是希望初始化为20,但是父类优先初始化,导致初始化为10。

        //例子里面已经将这种错误处理了

扩展类的特质

        class Logged{
                val number = 10
        }
        trait Account extends Logged{
                override val number = 20
                val array = new Array[String](number)
        }

        //特质是可以extends类的

自身类型

 没什么用

背后发生了什么

        trait Logged{
                val number = 10
        }

        //其实还是被翻译成了interface class

        trait Logged{
                val number = 10
                def aa()={
                        println("abcd")
                }
        }

        //其实还是被翻译成了interface class+一个静态类,里面是aa的静态方法

以上是关于从零学scala文件和正则表达式特质的主要内容,如果未能解决你的问题,请参考以下文章

QRegexp 特质(与 perl 相比):如何在没有惰性量词的情况下编写此正则表达式?

Scala的文件读写操作与正则表达式

从零开始让你掌握Python的正则表达式

教你从零开始学习java正则表达式

怎样在scala正则表达式提取器中使用小括号

Scala正则和抽取器:解析方法参数