zoukankan      html  css  js  c++  java
  • 从零学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的静态方法

  • 相关阅读:
    编译Excel遇到的DialogBoxW宏的实参不足问题
    C# 简单连接数据库并执行SQL查询语句
    AutoCAD VBA 遍历所有对象
    VBA: 错误消息:"类未注册"插入用户窗体
    解决Qt程序发布时中文乱码问题
    Qt操作excel
    HWND_BROADCAST的一个用法——修改环境变量,立即通知系统
    VC环境使用XML解析器(TinyXML)编程
    C++ XML解析之TinyXML篇(转载)
    C/C++枚举目录中的文件或文件夹
  • 原文地址:https://www.cnblogs.com/wuxiaolong4/p/11830178.html
Copyright © 2011-2022 走看看