spark 学习

1.Scala中有哪些常见符号?
2.本文讲了哪些符号?
3.你对符号的理解是什么?
4.<-,->,=>,Int=,_ 它们含义是什么?用在什么地方?






当我们学习spark的时候,我们知道spark是使用Scala语言开发的,由于语言是相通的,所以对于传统程序员【Java,.net,c等】,我们能看懂Scala程序是没有问题的。但是当我们看到它的时候,却傻眼了。那么多符号,左箭头,右箭头,下划线等等搞得摸不着头脑。

看来如果想顺利的学习,我们必须学一下Scala了。很多都是从变量定义,函数,类等入门。由于我们可能有些其他语言基础,这里我们从Scala符号入门。一文能帮助大家阅读比较常见的Scala程序。


Scala符号
如果你学过其它语言,特别是.net语言,那么你能看懂Java语言。无论是C,C++,还是其它语言,它们的变量,函数的定义都是差不多的。你能知道这是一个函数,并且大概懂得它实现了什么。但是如果你阅读过Scala代码,你会感觉摸不着头脑。里面有各种奇葩符号,比如:<-,->,=>,Int=,_ ,甚至还有空格。同样还有没有见过的关键字,with,apply。

我们来看看这些符号都用在什么地方:
第一个
:这个符号<-用在什么地方,比如用于for循环,
<-用于遍历集合对象(可遍历对象)B,在每次遍历的过程中,生成一个新的对象A,这个A是val,而不是var,然后对循环体中对A进行处理,<-在Scala中称为generator。 不需要显式的指定A的类型,因为Scala使用自动推导的方式根据B的元素类型得出A的类型
示例1:

[Bash shell] 纯文本查看 复制代码
1
2
for (arg <- args) 
println(arg)


上面是什么含义?
循环args,打印出里面的元素

示例2:

[Bash shell] 纯文本查看 复制代码
1
2
for (i <- 0 to 2) 
print(greetStrings(i))


上面的含义是遍历一个数组

[Bash shell] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
val A= new Array[String](3) 
 
A(0) = "Hello"
A(1) = ", "
A(2) = "world!\n"
 
for (i <- 0 to 2) 
print(A(i))



这个符号其实很碍眼,导致你可能根本弄不清楚为什么要搞这么个符号。而且很可能被我们误认为是一个负号。这样就增大了我们的阅读难度。但是如何你习惯了,其实Scala还是不错的,间接而且思想跟别的语言有很大的区别。
这里出现的英文to,也是比较奇怪的,我们看到过变量和函数使用英文,但是在for语句中使用英文,这也太随意了,不知道的以为是在做阅读理解。其实这里的to,是0的一个方法,全写

[Scala] 纯文本查看 复制代码
1
for (i <- 0.to(2))



第二个符号->
->方法是所有Scala对象都有的方法,比如A->B,->方法调用的结果是返回一个二元的元组(A,B)
这个符号用于什么地方,比如map映射

Map(映射)是一种可迭代的键值对(key/value)结构。

// Map 键值对演示
val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
上面是定义map,那么map该如何操作:

Scala Map 有三个基本操作:
方法 描述
keys 返回 Map 所有的键(key)
values 返回 Map 所有的值(value)
isEmpty 在 Map 为空时返回true


实例
以下实例演示了以上三个方法的基本应用:

[Bash shell] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
object Test {
   def main(args: Array[String]) {
      val colors = Map("red" -> "#FF0000",
                       "azure" -> "#F0FFFF",
                       "peru" -> "#CD853F")
 
      val nums: Map[Int, Int] = Map()
 
      println( "colors 中的键为 : " + colors.keys )
      println( "colors 中的值为 : " + colors.values )
      println( "检测 colors 是否为空 : " + colors.isEmpty )
      println( "检测 nums 是否为空 : " + nums.isEmpty )
   }
}


执行以上代码,输出结果为:

[Bash shell] 纯文本查看 复制代码
1
2
3
4
5
6
$ scalac Test.scala
$ scala Test
colors 中的键为 : Set(red, azure, peru)
colors 中的值为 : MapLike(#FF0000, #F0FFFF, #CD853F)
检测 colors 是否为空 : false
检测 nums 是否为空 : true



map映射与map函数的区别
同时有一个小小的不同:
如果刚接触map函数会让我们特别的困惑和难懂。
~~~~~~~~~~~~~~~~~~~~~~~~~~~


map函数:

函数式编程都有一个map函数,map函数就像一个加工厂,传入一个函数,利用这个函数将集合里的每一个元素处理并将结果返回。

aList.map(processFunc)//就这么简单,aList中的每一个元素将会变成processFunc的返回值。 这个processFunc一般都是匿名函数,因为用过一次后就用不到了。

[Bash shell] 纯文本查看 复制代码
1
2
val l = List(1,2,3)
var ll = l.map(x => x*x)//返回 ll=(1,4,9)





~~~~~~~~~~~~~~~~~~~~~~~~~~~

第三个符号=>
这些符号说大于不是大于,说等号不是等号。它代表什么意思.我们来看下面内容:
<ignore_js_op> 
这个咋看到不明所以,左边像参数传递,右箭头右侧像一个加法运算。而这个其实是Scala的匿名函数。
左边是参数,右边是函数体。在我们印象中,函数体一般都是在大括号中,而这里真让我们难以理解。
总之:方法参数=> 方法体这时候我们需要明白这是匿名函数
这就是Scala不走寻常路,而且其它的很多地方,都是这个样子。比如下面的函数定义等等。这里先给大家认识下Scala的匿名函数

[Bash shell] 纯文本查看 复制代码
1
2
val l = List(1,2,3)
var ll = l.map(x => x*x)//返回 ll=(1,4,9)


这里借用上面的内容,map里面的x => x*x就是一个匿名函数。
如果初学,我们可能不知道为什么要产生匿名函数,因为匿名函数基本上使用 一次,后面就用不到了。##################

这里扩展,写一下Scala函数定义的几种方式

[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.persia
 
object FuncReturnType {
   
   //写法一,始终待返回值
   def add(x:Int,y:Int):Int={
     x+y
   }
    
 
   def returnUnit():Unit={
     println("another way to return void")
   }
    
   //写法二,省略非Unit返回值;如果没有写返回值,则根据等号后面的东西进行类型推演,此种不提倡
   def test(x:Int)={
      x
   }
    
   //写法三,省略等号,返回Unit
   def returnVoid(){
     println("return void")
   }
    
   //写法四:省略花括号,如果函数仅包含一条语句,那么连花括号都可以选择不写
   def max2(x: Int, y: Int) = if (x > y) x else y
    
   def greet() = println("Hello, world!")
   
   def main(args:Array[String]):Unit ={
      println(add(1,2))
      println(test(1))
   }
 
}




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
对于右箭头,还有一个地方用到就是
匹配模式语句case与后面表达式的分隔符
例如
a match {
case 1 => "match 1"
case _ => "match _"
}
从这里让我们对符号是否有了新的理解,其实无论它是什么符号,它只起到分割的作用


第四个符号int=

int=,我们知道变量后面是一个等号是非常常见的,比如a=1,等,变量等于(=)这个确实难以理解。
下面来看下Scala是函数的定义,我们就能明白了,int=的含义

<ignore_js_op> 

scala中函数的定义是使用关键字def,然后函数名,括号中参数的定义,更是与传统语言反着来。Scala是参数在前,类型在后,以冒号(:)作为分隔符。返回值则是写在后面,函数的定义与函数体分隔符则是使用等号分割。单从函数的定义,我们就能看出Scala打破了传统的函数定义,除了函数定义,其它还有很多地方,都反映了Scala思想,没有以前Java,c等那么严格。Scala更像是一个思想的自由者,解放者,随心所欲,不管Java,.net,c等如何搞的,它是自成一家。

自成一家当然不止这一处,比如变量定义,for循环,case等都是做了很大的改变。比如:
for(i <- 1 to 5; j <- 1 to 5),for嵌套,这是我们所熟悉的两层for循环。

[Java] 纯文本查看 复制代码
1
2
3
4
for(i=1;i++;i<=5
for(j=1;j++;j<=5)
     {}
}


在比如for条件过滤。
我们肯定会这样

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
for(i=1;i++;i<=5
for(j=1;j++;j<=5)
     {
      if (!(i==3&&j==3)))
          {
                if(i!=2 || j!=2)
                 {
                  }
          }
     }
}


那么Scala如何表达

[Scala] 纯文本查看 复制代码
1
2
3
for(i<- 1 to 5; j <- 1 to i;if (!(i==3&&j==3)); if(i!=2 || j!=2)){
 
}


当然还有更多,大家可以在深入了解下
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
比如:
去掉了函数体定义时的“=”的函数一般称之为“过程”,过程函数的结果类型一定是
Unit。因此,有时定义函数时忘记加等号,结果常常是出乎你的意料的。
如:
def f(a:Int) {
println(a)
}
println(f(1))
输出结果:
1
()
没有返回值的函数的默认返回值是Unit。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

第五个“_”

在scala 中,符号“_”相当于java 中的通配符“*”。这个有很多的含义

1、作为“通配符”,类似Java中的*。如import scala.math._

2、:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 to 5:_*)就是将1 to 5当作参数序列处理。

3、指代一个集合中的每个元素。例如我们要在一个Array a中筛出偶数,并乘以2,可以用以下办法:
a.filter(_%2==0).map(2*_)。
又如要对缓冲数组ArrayBuffer b排序,可以这样:
val bSorted = b.sorted(_
4、在元组中,可以用方法_1, _2, _3访问组员。如a._2。其中句点可以用空格替代。

5、使用模式匹配可以用来获取元组的组员,例如
val (first, second, third) = t
但如果不是所有的部件都需要,那么可以在不需要的部件位置上使用_。比如上一例中val (first, second, _) = t

6、还有一点,下划线_代表的是某一类型的默认值。
对于Int来说,它是0。
对于Double来说,它是0.0
对于引用类型,它是null。(引:知乎黄辉煌


############################
进一步补充:
:::运算符
:::(三个冒号)表示List的连接操作,比如:

[Scala] 纯文本查看 复制代码
1
2
3
val a = List(1, 2
val b = List(3, 4
val c = a ::: b



其中a,b保持不变,a和b连接产生一个新表List(1,2,3,4),而不是在a上面做add操作。
Scala中的List不同于Java的List,Java声明final List javaList,表示javaList一旦初始化,那么不能再为它赋值,但是它其中的元素可以变化,


::运算符

::(两个冒号)表示普通元素与List的连接操作,比如:

[Bash shell] 纯文本查看 复制代码
1
2
3
val a = 1 
val b = List(3, 4) 
val c = 1 :: b



则c的结果是List(1,3,4),需要注意的是,1:: b操作,::是右侧对象的方法,即它是b对象的方法,而::左侧的运算数是::方法的参数,所以1::b的含义是b.::(1)

posted on 2018-03-05 11:52  还有梦  阅读(218)  评论(0编辑  收藏  举报

导航