Scala学习笔记
方法和函数的区别
-
Scala中的方法和Java中的方法相同,方法是组成类的一部分。方法有名字和签名,同时还有注解,以及方法的功能。
-
Scala中的函数是一个完整的对象,Scala中用22个特质(trait)抽象出了函数的概念。]\
例如:Function2的函数:
trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @specialized(scala.Int, scala.Long, scala.Double) -T2, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef { self => /** Apply the body of this function to the arguments. * @return the result of function application. */ def apply(v1: T1, v2: T2): R /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` */ @annotation.unspecialized def curried: T1 => T2 => R = { (x1: T1) => (x2: T2) => apply(x1, x2) } /** Creates a tupled version of this function: instead of 2 arguments, * it accepts a single [[scala.Tuple2]] argument. * * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` */ @annotation.unspecialized def tupled: Tuple2[T1, T2] => R = { case Tuple2(x1, x2) => apply(x1, x2) } override def toString() = "<function2>" }
其中:
// 以下两种定义函数的 val f1 = (i: Int, b: Int) => { i + b } var f2 = new Function2[Int, Int, Int]() { override def apply(v1: Int, v2: Int): Int = { v1 + v2 } }
- 方法不能作为单独的表达式而存在(参数为空的方法除外),而函数可以;
//m1 方法不可以 def m1(x:Int,y:Int)={ x+y } //f1方法本身就是一个对象,直接可以单独最为表达式存在 val f1 = (i: Int, b: Int) => { i + b }
2.函数必须要有参数列表,但方法可以没有参数列表
3.方法名是函数的调用,函数名只代表函数本身
//如果想要由编译器自动推断返回函数的类型,需要在返回函数的后面增加下划线,意味着函数不执行,而是用于返回 def f222():=>Unit= { f22 _ //使用函数 } def f222():Unit= { f22 //调用方法 }
Scala中的隐式转换
-
什么是隐式转换
示例代码:
object ImplicitTest { def main(args: Array[String]): Unit = { //如果没有implicit的隐式函数,那么声明的变量i会出现错误 implicit def f(i:Double): Int ={ i.toInt } var i:Int =1.0 } }
-
隐式函数: 通过iimplicit的关键字声明的带有单个参数的函数,这种函数将会自动应用,将从一种类型转换为另一种类型。
-
隐式函数与函数名无关,与函数的参数类型和返回值类型有关
-
隐式函数可以有多个,但要保证只有一个隐式函数能被识别
object ImplicitTest { def main(args: Array[String]): Unit = { implicit def f(i:Double): Int ={ i.toInt } implicit def f1(i:Float):Int={ i.toInt } /* implicit def f2(i:Double):Int={ //必须保持在作用域内,参数类型和返回类型唯一 i.toInt }*/ var i:Int =1.0 } }
-
隐式类,给类增加功能
object ImplicitTest2 { def main(args: Array[String]): Unit = { implicit def f(m:Mysql)={ new DB } val mysql: Mysql = new Mysql mysql.add() mysql.update() mysql.delete() //delete的方法是通过隐式转换得到的,可以进行功能扩展 } } class Mysql{ def add()={ println("增加数据") } def update()={ println("更新数据") } } class DB{ def delete()={ println("删除数据") } }
-
隐式值: 隐式变量,将某个形参的变量标记为implicit,所以编译器会在方法省略参数的情况下去搜索作用域内的隐式值作为缺省参数
object ImplicitValTest { def main(args: Array[String]): Unit = { implicit var name ="hello"; def f1(implicit name:String ="java"): Unit ={ println(name +"\thello") } f1 //结果为 hello hello f1("scala") //结果为 scala hello //编译器的传值优先级为 传值>隐式值> 默认值 } }
-
-
隐式类
-
特点
- 其所带的构造参数只能有一个
- 隐式类必须定义在 类,伴生对象,或包对象里,及隐式类不能是顶级的
- 隐式类不能是case class
- 作用域内不能有与之名称相同的标识符
-
示例代码
object ImplicitClassTest { def main(args: Array[String]): Unit = { implicit class DB1(val m:Mysql1){ def addSuffix():String={ m + "scala" } } val mysql = new Mysql1 mysql.helloMysql() mysql.addSuffix() } } //class DB1{ } class Mysql1{ def helloMysql()={ println("Mysql") } }
-