一元操作符:
后置一元操作符: 后置一元操作符就相当于普通的无参方法。 |
前置一元操作符: 前置操作符被默认转成对名为 unary_操作符 的方法调用,例如:-a和a.unary_-一样 |
赋值操作符:
定义形如:操作符= 的操作符
例如:
a 操作符= b
a 操作符= b
等价于:
a=a 操作符 b
注意:
- <=,>=和!=不是赋值操作符
- 以=开头的操作符不是赋值操作符
在scala中,所有的操作符都是左操作符,除了:
- 以冒号(:)结尾的操作符
- 赋值操作符
apply和updata方法:
调用f(arg1,arg2,...)事实上是调用f.apply(arg1,arg2,...)
调用f(arg1,arg2,...)=value事实上是调用f.update(arg1,arg2,...,value)
unapply和unapplySeq方法也叫做提取器
例如:var Fraction(a,b)=Fraction(2,3)
如果Fraction是定义了unapply方法的,那么就有a=2,b=3的结果。至于返回什么由用户自己定义。
unappluSeq和unapply差不多,unappluSeq可以定义任意返回长度。
“++”操作符,用来连接两个数组。
yield语法,和python中的差不多:
yield语法会产生一个生成器,在scala中也可以当做一个Array的形式。
type关键字:
type可以用来重命名类型,例如 Type MyString = String,在以下的就可以把MyString当做String来使用。
lazy关键字:
使用lazy关键词定义的变量会在第一次访问的时候初始化。
lazy val、val、def的不同:
lazy val:在第一次调用的时候执行,执行后保存下来。
val:在定义的时候执行。
def:每次调用都会重新执行。
在多步骤,多次迭代的代码中,使用lazy能够保存下更多的步骤,这样就有更大的优化空间
implicit关键字:
这是隐式转化的关键字,是scala中的一大特色:
隐式转换:
例子:
class RichFile(
val file:File){
def read = Source. fromFile(file.getPath()).mkString } object Context{ implicit def file2RichFile(file:File)= new RichFile(file) //File -> RichFile } object Hello_Implicit_Conversions { def main(args: Array[ String]) { import Context. file2RichFile println( new File( "E: \\ WangJialin.txt") .read) }
}
黄底部分用了隐式转换
|
隐式参数:
隐式参数的作用其中一个就是提供默认值,例如:
object Context_Implicits{
implicit val default:String = "Flink" } object Param{ def print(content:String)(implicit language:String){ println(language+ ":"+content) } } object Implicit_Parameters { def main(args: Array[ String]) { Param. print( "Spark")( "Scala") import Context_Implicits._ Param.print("Hadoop") } } |
隐式类:
代码示例:
object Context_Helper{
implicit class FileEnhancer(file : File){ def read = Source.fromFile(file.getPath).mkString } implicit class Op(x:Int){ def addSAP(second: Int) = x + second } } object Implicits_Class { def main(args: Array[ String]){ import Context_Helper._ println( 1.addSAP( 2)) println( new File( "E: \\ WangJialin.txt").read) }
}
隐式类直接用来增强类的功能。
|
隐式对象:
abstract class Template[
T] {
def add(x: T, y: T): T } abstract class SubTemplate[ T] extends Template[ T] { def unit: T } object Implicits_Object { def main(args: Array[ String]) { implicit object StringAdd extends SubTemplate[String] { override def add(x: String, y: String) = x concat y override def unit: String = "" } implicit object IntAdd extends SubTemplate[Int] { override def add(x: Int, y: Int) = x + y override def unit: Int = 0 } def sum[ T](xs: List[ T])( implicit m: SubTemplate[T]): T = if (xs.isEmpty) m.unit else m.add(xs.head, sum(xs.tail)) println(sum( List( 1, 2, 3, 4, 5))) println(sum( List( "Scala", "Spark", "Kafka")))
}
}
这个的用途还不是特别了解
|
override关键字:
在Scala中,
1) 可以用override val 覆盖父类或特质中不带参数的def , 但反过来不行, 比如
|
class
Father{
def
name
=
"Archer"
def
score()
=
1.0
val
id
=
12
}
class
Children
extends
Father{
override
val
name
=
"Jack"
override
val
score
=
2.0
override
def
id
=
10
// error: error overriding value id in class Father of type Int; method id is not stable
}
|
个人认为这条规则可以这么记忆,因为def表示一个函数,函数返回值都有一个确定的范围,比如上面的name函数,它的返回值范围是全体的字符串,由于val 表示一个常量,值的范围已经却确定,因此如果子类要覆盖父类的同名成员,其值的范围不能更宽泛, 否则就破坏了里氏代换原则。显然, def 所蕴含的范围要比 val 广(注: 这段话是我瞎说,只是方便记忆)
2. 子类的def 可以 override 父类的def, 比如
|
class
Father{
def
name
=
"Archer"
def
say()
=
"go to bed"
def
moveTo(x
:
Int, y
:
Int)
=
println(
"move to ("
+x+
","
+y);
}
class
Children
extends
Father{
override
def
name()
=
"Jack"
override
def
say()
=
"I'm not tired"
override
moveTo(x
:
Int, y
:
Int)
=
super
.moveTo(x,y)
}
|
|
class
Father{
def
credit
=
"abc"
def
credit
_=
(s
:
String)
=
(println(
"s"
))
}
class
Children
extends
Father{
override
var
credit
=
"fff"
// var can override a dual def
}
|