欢迎来到天剑厚德,这里有最新的大数据技术原创分享。

Scala这些语法糖和新概念

scala healthsun 0评论

下面就来说一下Scala这些语法糖和新概念:

一、单例对象(singleton object)

scala没有static关键字,搞出了个object关键字来新建单例对象。在单例对象中的成员都是static的。所以要写util类或者单例一般都要用这个Object。

object xxUtil{  
  def process(xx:String):String = {  
    xx
  }  
}

二、伴生对象和伴生类(companion object & companion class)、独立对象(standalone object)

这两个概念是相互的。假设有object A 和 class A 两个同名了。这时候就可以说:object A是class A的“伴生对象”;class A是object A的“伴生类”。当一个object B没有同名的class B的时候,object B就叫“独立对象”。

伴生带来的特权就是:它们可以互相访问私有成员。

class和object的区别: 1、单例对象不能用new来初始化。 2、单例对象不能带参数。 3、单例对象在第一次调用的时候才初始化。

三、略坑的函数调用语法糖

1、神奇的点号省略。

虽然有的时候带来一定方便,不过组合lambda特性等东西,代码简直就能亮瞎你的氪金狗眼。

//无参数  
"hello" toUpperCase  
"hello".toUpperCase  
"hello".toUpperCase()  
//一个参数  
"hello".indexOf "h"  
"hello" indexOf "h"  
//多个参数  
"hello world" substring (0, 3)  
//全部搞在一起  
"hello world" substring (0, 3) toUpperCase() indexOf "h"  
//配合上匿名函数  
Array(1,2,3) map ((i:Int)=> i+1)  
1 to 3 map ((i:Int)=> i+1)

2、神奇的for Scala代码

//这个for挺正常的吧?  
for(i <- 1 to 4) println(i)  
//这个呢!  
for(i <- 1 to 4 if i > 1) println(i)  
//这个呢!!!  
for(i <- 1 to 4 if i > 1; if i < 4; if i % 2 ==0) println(i)
//方法1
for (i <- 1 until 3) {
print(i + ",")
}
//方法2
(1 to 3).foreach(i => print(i + ","))

3、神奇的花括号{}代替小括号()语法 据说,如果函数调用只传入一个参数,花括号可以代替小括号,scala粑粑不会打你屁股。

Scala代码

println("hello")  
println{"hello"}  
 
def xx(i:Int)(j:Int) = i+j  
xx(1){2} //result: 3  
(xx(1)_){3} //curry化调用  
(xx(1)_)(3) //curry化调用,不信你不懵  
 
//看了上面的还没懵?那就再来个  
def xx(i:Int)(j:(Int)=>Int) = j(i)  
xx(1){i=> i+10}  
 
//有爱的一面  
//假设我定义一个hbase的scan方法  
def scan(tableName:String, cf:String, startRow:String, stopRow:String)(processFn:(Result)=>Unit) = {  
//...  
}  
//那么我可以这么自然的调用  
scan(t1, cf, startRow, stopRow){ r =>  
  //TODO process result  
}  

4、神奇的byName函数和调用 为了让自己定义的方法看起来和scala内建语法一样“和谐”,搞出了一个byName参数和byName函数。

Scala代码

//抄袭scala编程的例子  
def myAssert(pred:()=>Boolean) = if(!pred()) throw new AssertionError  
myAssert(()=> 5<3) //()=> 5<3匿名函数看起来是不是不爽?  
 
//因为()=> 5<3 的调用看起来不自然。所以要将()这部分去掉。  
def myAssert2(pred: =>Boolean) = if(!pred) throw new AssertionError  
myAssert2(5<3) // 这样看起来爽多了。

四、类型的上下界,view bounds(视界) 与 <%

class foo[T <% A]{...} //弱上界<%。关系较弱:T能够隐式转换为Ordered[T] 
class foo[T <: A]{...} //上界 <:。T必须是A的子类,A是T的类型上界。
class foo[T >: A]{...} //下界 >:。T必须是A的父类,A是T类型的下界。
其实<: 和 >: 就等价于java范型编程中的 extends,super
<%的意思是“view bounds”(视界),它比<:适用的范围更广,除了所有的子类型,还允许隐式转换过去的类型

五、协变和逆变

+T: 协变:class Queue[+T] {}。如果C<:A,则Queue[C] <: Queue[A]  
-T: 逆变 : class Queue[-T] {}。如果C<:A,则Queue[C] >: Queue[A]

六、隐式转换

隐式转换,是对应于显式的转换来说的。比如有”1234″.toInt,这就是显式的转换,不直接调用toInt方法转换的就是隐式转换。

Scala代码

implicit def str2Int(s:String):Int = Integer.parseInt(s) //隐式str转int  
def add(a:Int, b:Int) = a+b  
add("1",2) //先把"1"隐式转换为1,再加起来。

七、case类

case类是什么,case类就是一个class,可是能用来做模式匹配。所以搞出这么个东西。。。

case类和一般类的不同点:

1、会有和类名一样的工厂方法。不需要使用new来创建这个类对象。

Scala代码

case class Var(name:String)  
val v1 = Var("peter") //和类名一样的工厂方法  

2、case类的参数列表默认是val的。 3、自动添加了toString,hashCode和equals的自然实现。

case类的最大的用途就是用来做模式匹配。

Scala代码

case class Var(name:String)  
val v1 = Var("peter")  
v1 match {  
  case Var(name) => name  
  case _ =>  
}  
//匹配出name为peter

八、模式守卫 模式守卫(pattern guard)接pattern之后,开始与if。只有模式守卫返回true才算成功。

Scala代码

10 match {  
case n:Int if 1< n => println(n) //if到=>之前,这段为模式守卫  
case _ =>  
}  

九、scala中Seq操作符:: , +:, :+, :::, +++的区别

:: 该方法被称为cons,意为构造,向队列的头部追加数据,创造新的列表。用法为 x::list,其中x为加入到头部的元素,无论x是列表与否,它都只将成为新生成列表的第一个元素,也就是说新生成的列表长度为list的长度+1(btw, x::list等价于list.::(x))

:+和+: 两者的区别在于:+方法用于在尾部追加元素,+:方法用于在头部追加元素,和::很类似,但是::可以用于pattern match ,而+:则不行. 关于+:和:+,只要记住冒号永远靠近集合类型就OK了。

++ 该方法用于连接两个集合,list1++list2

::: 该方法只能用于连接两个List类型的集合

scala> "A"::"B"::Nil
res0: List[String] = List(A, B)

scala> "A"+:"B"+:Nil
res1: List[String] = List(A, B)

scala> Nil:+"A":+"B"
res2: List[String] = List(A, B)

scala> res0 ++ res1
res3: List[String] = List(A, B, A, B)

scala> res0 ::: res1
res4: List[String] = List(A, B, A, B)

scala> res0 :: res1
res5: List[java.io.Serializable] = List(List(A, B), A, B)

十、scala中Nil,Null,None,Nothing的区别

Nothing Nothing是所有类型的子类,它没有对象,但是可以定义类型,如果一个类型抛出异常,那这个返回值类型就是Nothing。

Null Null是AnyRef的子类(引用类型) null是Null唯一的对象。

None None是Option的一个子类,一个Some集合,一个None,如果Option中没有值,则返回None。

Nil Nil是一个空List,定义为List[Nothing],所有Nil是所有List[T]的子类

如果你觉得这篇文章或者我分享的主题对你有帮助,请支持我继续更新网站和主题 !捐赠本站
喜欢 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址