柳市网站建设,wordpress变慢了,龙岩智能微站,网站开发 东莞1、伴生对象 形如#xff1a; 有一个类 class Test{ } 一个object和该类同名 object Test{ } object Test的作用类似于静态类#xff08;工具类#xff09;#xff0c;其中的所有成员都是静态的#xff0c;在object Test中可以直接访问class Test的成员#xff1b;… 1、伴生对象 形如 有一个类 class Test{ } 一个object和该类同名 object Test{ } object Test的作用类似于静态类工具类其中的所有成员都是静态的在object Test中可以直接访问class Test的成员反之class Test中要通过object Test来引用其成员例如使用Test.的方式 2、apply方法 class中的apply是一个比较特殊的方法通过这个class new 出来的对象可以直接通过对象()这样的方式来调用apply方法 object中的apply比较常用例如通常使用数组时是下面这样的代码 val arr new Array[Int](3)
arr(0) 1
arr(1) 2
arr(2) 3 但是在scala中可以通过伴生对象的apply方法我们可以很方便的构建类的对象而不必知道和操作这个过程如下 val arr Array(1,2,3) 通过伴生对象的apply方法我们可以很方便的构建类的对象而不必知道和操作这个过程在apply方法中其实也是new出一个Array并在其中做好了初始化操作 源代码如下 /** Creates an array of Int objects */// Subject to a compiler optimization in Cleanup, see above.def apply(x: Int, xs: Int*): Array[Int] {val array new Array[Int](xs.length 1)array(0) xvar i 1for (x - xs.iterator) { array(i) x; i 1 }array} 3、继承 没啥好说的概念和其他语言一样只是语法有点区别 class Father(name:String){
...
}
//构造子类的时候会先构造父类所以要将父类构造函数需要的参数给它
class Son(name:String,age:Int) extends Father(name){
...
} 4、trait特质 trait可以当接口来用但是和其他语言的接口有些不同trait里面竟然还可以有方法的定义 那么这样和抽象类不是一样的了干嘛还要trait Scala中也是单继承也就是说一个类只能继承一个父类需要有很多子类的特性的时候就可以通过继承多个trait来实现可以把抽象类看成是一个统一的模板trait则是其他七七八八的装饰可加可减灵活性高 在Scala中如果一个class或者一个trait直接继承了另外一个trait那么语法是一样的 trait Test{
...
}class Test1 extends Test{
...
} 当多重继承时trait要使用with关键字构造顺序从左往右且不重复构造 class Human{...}
trait ITeacher extends Human{...}
trait IBasketballPlayer extends Human{...}
class BasketballTeacher extends Human with ITeacher with IBasketballPlayer{...} 由于ITeacher和IBasketballPlayer都继承了Human理论上在构造他们的时候会去构造他们的父类也就是Human但是由于Human之间在构造BasketballTeacher 的时候已经构造过了所以这里不再重复构造 上面代码演示的是在定义class的时候混入trait 实际上也可以在new object的时候使用这样可以在具体的场景中定义具体处理的对象和定义class的时候直接混入的区别是前者new出来的所有object都带有trait特质的后者只作用在一个单一的object class Human{...}
trait ITeacher extends Human{...}
trait IBasketballPlayer extends Human{...}val t1 new Human with ITeacher with IBasketballPlayer{
//如果有抽象方法在此重写
} 需要注意的是混入的trait必须都继承自同一个父类 trait的AOP实现 trait DoSomething {def work
}class Do extends DoSomething{override def work: Unit {println(working!)}
}trait BeforeAndAfter extends DoSomething {abstract override def work: Unit {println(init...)super.workprintln(destroy...)}
}object test {def main(args: Array[String]) {val worker new Do with BeforeAndAfterworker.work}
} 上面的代码中使用trait实现了一个简单的AOP编程实例 首先定义了一个trait DoSomething里面有一个抽象方法work class Do继承自DoSomething并实现了具体的work方法 这时new一个Do的object之后调用work应该打印出一行记录 之后定义了另外一个trait BeforeAndAfter也继承了DoSomething并重写work 在其重写的方法中将父trait的work方法放在初始化和销毁的操作之间由于父trait的work方法是抽象的此时又调用了这个抽象方法所以这个重写的work仍然是抽象的要加上abstract关键字 在new Do的object的时候混入这个trait就可以实现AOP代码执行过程应该是这样的 1、调用worker的work方法由于混入了trait所以实际调用的是这个trait里面的work 2、这个trait里面的work先进行了初始化操作然后调用父trait的work而这个方法的具体实现是在Do类中完成的所以又调用了Do类中的具体work实现 3、work调用完成之后进行销毁操作 5、包对象 包对象的定义及作用如下 //这是一个包对象
package obejct Person{...}
//这是一个包的定义
package Person{
//此时在这个包的作用于范围之内可以直接访问包对象的成员
}//使用这种语法的import意思是将scala包中的StringBuilder隐藏起来不使用使用别的包的StringBuilder
import scala.{StringBuilder _} 6、文件操作 //读取本地文件
val localFile Source.fromFile(file path)
val lines localFile.getLines
//读取网络文件
val networkFile Source.fromURL(file url)
//创建一个写入器
val writer new PrintWriter(new File(file path))
writer.println(something to write)
writer.close
//控制台读取
Console.readLine 7、正则表达式 //可以直接使用字符串.r的方式返回一个Regex对象
val regex1 [0-9].r
//三个引号表示表达式中的符号都是原意而不是转义符如\
val regex2 \s[0-9]\s.r
//Regex对象可以直接调用findAllIn/findFirstIn等方法
regex1.findAllIn(1234 dqd qwdq)//该方法会返回全部匹配项 正则表达式和模式匹配相结合 val regex ([0-9]) ([a-z]).r
val line 123 abc
line match {
//line如果符合regex1规则会将其自动匹配成(num,str)格式
case regex(num, str) println(num : str)
case _ println(~~~~~~~~~)
} 8、内部函数的定义 开发过程中经常将各个子功能定义为一个个函数在通过一个统一入口函数在调用这个子函数 但是这样存在一个问题入口函数和子函数通常是定义在一起的既然入口函数可以被外部调用那么子函数同样也可以 这就不是我们想要的效果了我们需要实现的是外部只能调用入口函数而对于其他的子功能都是不可见的 这也就是高内聚低耦合的思想 在Scala中函数是一等公民意味着函数可以当做变量成员来使用 那么在函数中可以定义变量也就可以定义函数 这就是内部函数 def portal{//内部函数定义def action1{}def action2{}...调用内部函数action1action2
} 9、闭包 简单的说闭包就是指在一个函数中能够访问另外一个函数的变量必须要访问这个变量才能完成函数的工作读取这个变量之后这个函数就关闭执行成为闭包 一个简单的闭包例子 //这个函数中要完成功能必须要知道more的值
def add(more:Int) (x:Int) x more
//传入more的值为1返回值其实还是一个函数x1
val a add(9)
val b add(90)
//调用这个返回的函数传入x1
a(1)
b(10) 10、高阶函数 高阶函数简单的说就是 参数是函数 的函数 例如map、reduce等需要传入匿名函数的函数 具体操作就不详细说明了因为高阶函数太多了 使用方法都是差不多的 11、SAM转换 即Simple Abstract Method 在例如Java等语言中代码通常是这样子写的 jButton.addActionListener(new ActionListener{override def actionPerformed(event:ActionEvent){counter 1}
}) jButton的addActionListener需要一个格式为(event:ActionEvent)Unit的方法上面的代码中直接new出了一个ActionListener并重写其方法传入 这叫做样本代码即符合这个样本格式的方法才能使用 而很多时候addActionListener这类的方法并不需要知道这么多信息它只需要我们给它一个方法就行了而不是一大堆的重新new对象重写方法 在Scala中是这么解决问题的 //这是一个隐式转换其实起到的作用就是样本代码名字任意只要参数和返回值是符合固定格式的即可
implicit def makeAction(action:(ActionEvent) Unit) {new ActionListener{override def actionPerformed(event:ActionEvent){action(event)}
}//有了上面的隐式转换我们就可以很简洁的直接将方法当做参数传入
jButton.addActionListener((event:ActionEvent) counter 1) 此时在这个界面的所有地方都可以传入(ActionEvent) Unit类型的函数给需要的函数了 总结SAM转换 借助隐式转换将样本代码省去 传入一个方法自动扫描当前区域的隐式转换定义了样本代码如果转换成功就可以调用 12、Currying函数柯里化 函数的柯里化即将原来接受两个参数的函数变成新的接受一个参数的函数的过程。 简单的例子 //多参数的函数
def add(x:Int,y:Int) x y
add(1,2)
//接受一个参数的函数
def add(x:Int) (y:Int) x y
add(1)(2) 对于只接受一个参数的函数格式是不是挺熟悉的在之前的闭包中使用的就是这种格式的函数 Scala中支持定义简介的柯里化函数 def add(x:Int)(y:Int) x y 柯里化的作用有很多其中一个就是用来做类型推断 在一些场合Scala编译器可以通过第一个参数的类型推荐第二个参数的类型以便进行一些操作 13、模式匹配 Scala的模式匹配类似于switch但是更加灵活格式如下 val line ...
line match{case ... ......case _ ...
} 每个case都有返回值没有特殊指定的话 case分支不用break case后可以用常亮变量表达式方法等 模式匹配还有很多其他的特殊的用法 例如匹配typearray、list、tuple格式 def match_type(t:Any) t match{case i:Int println(Int)case s:String println(String)case m:Map[_,_] m.foreach(println)
}def match_array(arr:Any) arr match{//数组中只有一个0的匹配成功case Array(0) ...//数组中有任意的两个数匹配成功case Array(x,y) ...//数组中第一个为0还有任意多个元素的匹配成功case Array(0,_*) ...
}def match_list(lst:Any) lst match{//List中有一个0的匹配成功Nil表示一个空的List::运算符是从右至左运算的表示空List加上一个0元素即为只有一个0的List集合case 0 :: Nil ...//List中有任意的两个数匹配成功case x :: y :: Nil ...//集合中第一个为0还有任意多个元素的匹配成功tail表示List中除了第一个元素外的所有元素case 0 :: tail ...
} 14、样例类和样例对象 通常在系统开发中我们需要自己定义一些数据结构来进行统一的消息传递例如经常使用的Model 在Scala中使用样例类和样例对象来完成这个功能 定义的格式如下 case class Person(...)
case object Person1(...) 15、嵌套的样例类和模式匹配结合 abstract class Item{...}
case class Book(name:String,price:Int) extends Item
//BookList中嵌套了一个Book的样例类
case class BookList(num:Int,books:Book*) extends Itemdef match_caseclass(item:Item) item match{//匹配BookList用占位符_代替的属性都不关心只要Book的name属性case BookList(_,Book(name,_),_*) ...//可以使用别名Book的方式进行模式匹配后面的方法体中可以使用别名直接操作case BookList(_,b1 Book(_,_),other _*) ...
} 未完待续… 转载于:https://www.cnblogs.com/jchubby/p/5449381.html