前言

在前面的章节中, 我们介绍了如何在Eclipse内安装Scala环境. 本章开始, 我们将讲解下Scala的基本语法.

PS: 1. 个人虽然没有想转Scala语言开发的思想, 但是近来Scala语言被各种媒体炒的火热. 了解下总没有坏处. 就个人而言, 还是非常喜欢Java的简洁语法的.
2. 另在学习过程中, Scala经常会去调用Java的语法. 个人感觉, Scala在某些方面做的仍然还没有到位和完全. 但是, 对于Spark等的大数据开发, Scala或许是一门不错的语言.
3. Eclipse中的Scala IDE(Oxygen)做的仍然不是非常完善. 最需要的查看Scala内的源码的功能缺失, 后期Scala的开发可能会转向使用IDEA进行开发.(虽然, 个人非常不喜欢IDEA那些花里胡哨的所谓自动化功能.)
4. 本文所涉及的代码, 都可以在我的github项目的https://github.com/SeanYanxml/arsenal 的 arsenal-scala/quick-scala下找到.


前置准备

Eclipse Scala环境的配置 根据上述的文章配置好相关的开发环境. (IDEA略过此步骤)

Maven的Pom.xml文件依赖. 由于之前的Maven创建模板内, Scala的某些依赖的版本号已经不适合个人使用的版本. 个人将其替换成了相应的版本. 读者可以根据个人需要, 从 https://mvnrepository.com/ 上查询并选择需要的版本.

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.yanxml</groupId><artifactId>quick-scala</artifactId><version>0.0.1-SNAPSHOT</version><name>${project.artifactId}</name><description>My wonderfull scala app</description><inceptionYear>2010</inceptionYear><licenses><license><name>My License</name><url>http://....</url><distribution>repo</distribution></license></licenses><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><encoding>UTF-8</encoding><scala.tools.version>2.11</scala.tools.version><scala.version>2.11.8</scala.version></properties><dependencies><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.7</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scala-library</artifactId><version>${scala.version}</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scala-library</artifactId><version>2.11.8</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scala-compiler</artifactId><version>2.11.8</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scala-reflect</artifactId><version>2.11.8</version></dependency><!-- https://mvnrepository.com/artifact/org.scala-lang/scala-actors --><dependency><groupId>org.scala-lang</groupId><artifactId>scala-actors</artifactId><version>2.11.8</version></dependency><!-- Test --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!-- <dependency> <groupId>org.specs2</groupId> <artifactId>specs2_${scala.tools.version}</artifactId> <version>3.0</version> <scope>test</scope> </dependency> --><!-- https://mvnrepository.com/artifact/org.scalatest/scalatest --><dependency><groupId>org.scalatest</groupId><artifactId>scalatest_2.11</artifactId><version>3.0.0-M16-SNAP6</version><scope>test</scope></dependency><dependency><groupId>org.scalatest</groupId><artifactId>scalatest_${scala.tools.version}</artifactId><version>3.0.0-M16-SNAP6</version><scope>test</scope></dependency><!-- spark --><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.11</artifactId><version>2.2.1</version></dependency><!-- akka --><!-- https://mvnrepository.com/artifact/com.typesafe.akka/akka-actor --><dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-actor_2.11</artifactId><version>2.3.14</version></dependency><!-- https://mvnrepository.com/artifact/com.typesafe.akka/akka-remote --><dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-remote_2.11</artifactId><version>2.3.14</version></dependency></dependencies><build><sourceDirectory>src/main/scala</sourceDirectory><testSourceDirectory>src/test/scala</testSourceDirectory><plugins><plugin><!-- see http://davidb.github.com/scala-maven-plugin --><groupId>net.alchim31.maven</groupId><artifactId>scala-maven-plugin</artifactId><version>3.1.3</version><executions><execution><goals><goal>compile</goal><goal>testCompile</goal></goals><configuration><args><arg>-make:transitive</arg><arg>-dependencyfile</arg><arg>${project.build.directory}/.scala_dependencies</arg></args></configuration></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.13</version><configuration><useFile>false</useFile><disableXmlReport>true</disableXmlReport><!-- If you have classpath issue like NoDefClassError,... --><!-- useManifestOnlyJar>false</useManifestOnlyJar --><includes><include>**/*Test.*</include><include>**/*Suite.*</include></includes></configuration></plugin></plugins></build>
</project>

正文

从本节开始, 我们正式介绍Scala的语法.

本章主要介绍如下几个方面:

  • QuickStart - HelloWorld
  • 常量&变量
  • 判断(if)
  • 循环(while/for/map)
  • 数组(Array)
  • 元组(Tuple)
  • 集合(Map&List&Set)
HelloWorld

在进行学习之前, 先使用HelloWorld小程序判断当前的编译器环境是否配置完毕.

在Scala中, 主要有2种方式创建静态的Main方法. def main&extends scala.APP.

另外值得一提的是, 这边使用的是object的前缀, 千万不要使用class前缀. 这是初学者非常容易犯的错误.(笔者当初就因为这个问题, 以为是IDE环境的问题, 绕了好久. 希望各位引以为戒.)

object App {def main(args : Array[String]) {println( "Hello World!" )}
}
object HelloWorld extends App{println("HelloWorld")
}
常量&变量

在Scala中, 与Java一样. 也有8种基本数据类型, 但是不存在向Java内的那么复杂. 即不存在基础类与封装类(int & Integer)的区别. 而是统一的使用基础类.(Byte Short Int Long Float Double Char Boolean)

常量的定义使用val关键字, 变量的定义使用var关键字. 在定义的过程中, 可以直接指定变量&常量的数据类型, 也可以不进行指定, 由系统自动识别装配.(var hello = "123"/ var hello2:String = "hello")

@Test// 常见的变量与常量类型def variable(){// 常量// 使用val修饰的变量值是不可变的,相当于java里用final修饰的变量.val a = 1// false. val can not change.//  a = 2// 变量// < var a = xx >. scala会自动推断变量的类型.// < var a : type(Int,String,...) >. 可以通过值得scala变量的类型.var b1 = 1var b2: String = "hello"  }
判断(if)

Scala内的if判断与Java中的类似. 但是表达式更加的泛化, 并且可以直接赋值给变量. 并且if内的返回值可以是多种数据类型的.(详间下方Scala示例.)

# Java
int a=0;
if(a>0){a++;
}else{a--;
}
# Scaladef ifelse(){println("if---else---test")val x =  1// 判断x的值 返回值给yval y = if(x>0) 1 else -1println(y)// 支持混合类型表达式val z = if(x>2) 1 else "error"println(z)// 缺失else 相当于if(x>2) else()val m = if(x>2) 1println(m)// scala中有个Unit类, 相当于Java中的void.val n = if(x>2) 1 else()println(n)val k = if(x<0) 0 else if(x>2) 1 else -1println(k)}
代码块(Block)

Java中, 代码块是由{}中的代码体. 在Scala内也是如此. 唯一不同的是, Scala内的代码体是可以赋值的.

# Java
public static void main(String[]args){int a=0;int b=0;
}
# Scala@Test// 块表达式(如何确定block的返回值?)def block(){println("block---test")val x = 0val result = {if (x>0) -1 else 1}println(result)}
循环(For&While)

在Java内, 我们经常使用while/do-while/for三种循环体. 在Scala内, 我们也可以使用. 但是Scala中, 更经常使用formap()函数进行循环操作.

# java
public static void main(String []args){int a=2;while(a>0){a++;}do{a++;}while(a>0)for(int i=a;i>0;i++){a++;}
}
# Scala
@Test// 常见的for循环def forcycle(){println("for---cycle---test")// 遍历 to 是一个方法 1 to 10for(i <- 1 to 10){print(i)}println()// 数组的定义 (相当于使用数组的Object方法 也就是静态方法)val arr = Array("a","b","c")for(a<-arr){print(a)}println()// 循环带条件, 主要if判断前没有分号for(i<- 1 to 3; j<- 1 to 3 if i !=j){print(10*(i)+j+" ")}println()//for推导式: for的循环的循环体以yield开始, 该循环会构建出一个集合// 每次迭代生成集合的一个值val v = for(i<-1 to 10) yield i *10println(v)1.to(10).map(_*10)// 遍历数组val arr2 = Array(1,2,3)val t = for(i<-arr2) yield i*2println(t)// 偶数 奇数获取val arrTmp = Array(1,2,3,4,5,6,7,8)val arrResult = for(i<-arrTmp){if(i%2==0) i else()}val arrResult2  = for(i<-arrTmp ; if(i%2==0)) yield ival arrResult3  = for(i<-arrTmp ; if(i%2==0)) ival arrResult4 = arrTmp.filter(_%2==0)for(i <- 1 to arrTmp.length) print(arrTmp(i))for(i <- 0 until arrTmp.length) println(arrTmp(i))}

Scala do…while 循环

数组&元组

Scala内的数组与Java内数组的定义略有不同. 且插入和删除操作也非常不一样. Scala内通过+-来进行末尾增加和删除单个元素; ++来增加集合元素. 当然也可以通过insert()remove()函数进行插入和删除多个元素.

#Java
public static void main(String []args){String []array1= {"1","2","3"};String []array2 = new String[10];// 循环遍历1for(String str:array2){}// 循环遍历2for(int i=0;i<array2.length;i++){}
}
# Scala@Testdef initArray(){// Test1// 初始化一个长度为8的定长数组, 所有元素均为0val array1 = new Array[Int](10)// 直接打印定长数组, 内容为数组的hashcode值println(array1)// 将数组转换为缓冲, 可以看到数组内的内容// to buffer 将数组转换为缓冲println(array1.toBuffer)// Test2// 使用静态方法创建val array2 = Array[Int](10)println(array2.toBuffer)// Test3val array3 = Array("Hadoop","Strom","Spark")println(array3(1))// 变长数组// 如果想使用数组缓冲,需要导入 import scala.collection.mutable.ArrayBuffer包val arrayBuffer1 = ArrayBuffer[Int]()// 尾部追加一个元素 +=尾部追加元素arrayBuffer1 += 1// 尾部追加多个元素arrayBuffer1 += (2,3,4,5)// 追加一个数组 ++=arrayBuffer1 ++= Array(6,7)// 追加一个缓冲数组 ++=arrayBuffer1 ++= ArrayBuffer(8,9) // 打印缓冲println(arrayBuffer1)// 指定位置添加元素val arrayBuffer2 = ArrayBuffer[Int]()arrayBuffer2 += (1,2,3)// 在数组角标为0的位置 开始插入2个元素arrayBuffer2.insert(0, -1,0)// 在数组角标位置为8的位置删除2个雅俗arrayBuffer2.remove(1,2)}/*** 遍历数组的方式主要有2种* 1. for循环* 2. 使用until生成角标, 0 until 10 (包含0不包含10 前封后开)* 3. map方法* */@Testdef foreachArray(){// 初始化val array = Array(1,2,3,4,5,6)// 使用for循环for(i <- array){print(i)}// 使用角标 (有时候需要获取数组的下标)// .reverse可以将其进行反转for(i<-(0 until array.length)){print(array(i))}// 倒转遍历数组for(i<-(0 until array.length).reverse){      }// map方式// 方法转换为一个函数array.map(println(_))}/*** 转换数组, 生成一个新的数组* 1. yield方式* 2. map方法.* */@Testdef swapArray(){val array = Array(1,2,3,4,5)// 偶数取出来 乘以10val arrayOdd = for(i<- array;if i%2==0)yield i*10println(arrayOdd.toBuffer)// map 方式的隐式函数 (一步一步的简化方式)array.map((x:Int)=>x*10)array.map(x=>x*10)array.map(_*10)val arrayOddMap = array.filter(_%2==0).map(_*10)println(arrayOddMap.toBuffer)}/*** 与Array相关的其他方法.* * */@Testdef otherArrayFunction(){val array = Array(1,3,2,5,5)// 求和运算array.sum// 排序array.sorted// 倒叙array.sorted.reversearray.sortBy(x=>x)// 降叙array.sortWith(_>_)// 升序array.sortWith(_<_)// 写成方法体array.sortWith((x,y) => (x>y))array.sortWith((x,y) => (x<y))}
元组

数组中的元素都是相同元素. 但是要应对不同元素组成的集合. 这在Scala内提供了新的数据集合:元组.

    @Testdef initTuple(){// Tuple的三个值可以不相同.val tuple1 = (1,"Spark",2.0)// 映射和Map是特殊的元组 也就是对偶元组val pairTuple = ("T",5)var m = Map(("b",2),("a",10))m += pairTuplem += (("A",1),("B",2))// x y z的方式取值val tupleXYZ, (x,y,z) = (1,"Spark",2.0)val array = Array(("a",1),("b",2))// 转换为对偶元组array.toMap// 拉链操作val arrayZip1 = Array("a","b","c")val arrayZip2 = Array("1","2","3","4")// 拉链对应转换. 但是有多的元素则不会再使用.arrayZip1.zip(arrayZip2)}
集合

Scala内的常用集合除了数组元组外, 还有ListMapSet.
值得一提的是, Scala内有可变集合import scala.collection.mutable.HashSet与不可变集合import scala.collection.immutable.HashSet.不可变集合多用于多线程中的某些数据的共享.
其基本使用主要如下所示:


/*** Scala 的集合三大类型: 序列 Seq 集Set 映射Map.* 所有的集合都扩展自Iterable特质.* 在Scala中集合有可变(mutable)和不可变(immutable)两种类型.* immutable类型的集合初始化后即不可改变.(与val关键字不同. 主要用于多线程的常量场景.)* * * */
class QuickCollection {// Sequence 序列相关操作 @Testdef immutableListOperation(){val list = List(1,2,3)// 使用ListBufferval listBuffer = ListBuffer(1,2,3)listBuffer(1) = 200val newListBuffer = listBuffer.map(_*10)// 其他操作val list1 = List(1,2,3)val list2 = 0::list1val list3 = list1.::(0)val list4 = 0+:list1val list5 = list1.+:(0)// 将一个元素加入到list后面形成新的集合val lsit6 = list1 :+3val list0 = List(4,5,6)// 两个集合合并成为新的集合val list7 = list1++list0val list8 = list1 ++: list0}@Testdef mutableListOperation(){// 构建一个可变列表, 初始有三个元素1,2,3val list0 = ListBuffer[Int](1,2,3)// 创建一个空的可变列表val list1 = new ListBuffer[Int]// 向list1中追加元素, 注意没有生成新的集合list1 += 4list1.append(5)list1.append(1,2,3,4,5)list1 ++= list0val list2 = list1 ++ list0list0 ++= list1}// HashSet 也有Immutable与Muttable 可变与不可变的两个版本.@Testdef immuttableSetOperation(){val set1 = new HashSet[Int]()// 将元素与set1合并成为一个新的setval set2 = set1 +1// set中的元素不能重复val set3 = set1 ++ Set(5,6,7)val set0 = Set(1,2,3) ++ set1println(set0.getClass)}// 可变的set的相关操作@Testdef muttableSetOperation(){// 创建一个可变的HashSetval set1 = new scala.collection.mutable.HashSet[Int]()// 向HashSet内添加元素set1 += 2// add等价于+=set1.add(4)set1 ++= Set(1,3,5)// 删除一个元素set1  -= 5set1.remove(2)println(set1)}// 不可变Map@Testdef immutableMapOperation(){val map1 = new HashMap[String, Int]()}@Testdef mutableMapOperation(){val map1 = new scala.collection.mutable.HashMap[String, Int]()// 向Map内添加元素map1("spark") =1map1 += (("hadoop",2))map1.put("storm", 3)println(map1)//从map中移除元素map1 -= "spark"map1.remove("hadoop")println(map1)}@Testdef initMap(){// immutable 不可改变val map1 = Map("a"->1, "b"->2)// mutable 可以改变// import scala.collection.mutable.Mapval map2 = Map("A"->1, "B" ->2)// 访问和修改映射中的值map2("A")=2map2("C")=100map2+=("D"->999)map2+=(("F",2))//import java.util.HashMap// 载入Java的HashMapval hm = new HashMap()val map3 = Map(("a",1),("B",2))map3.getOrElse("C", "123")}
}

Reference

[1]. Scala 教程
[2]. Scala:HelloWorld
[3]. Scala(二) 基础语法

Scala语法(一) 基础语法(变量常量判断循环数组集合)相关推荐

  1. js php 数据类型判断,【js基础】变量类型判断

    类型判断方法比较: 如果需要想详细了解,请看下文: 注:原封不动复制备份,防止删帖 在JavaScript中,有5种基本数据类型和1种复杂数据类型,基本数据类型有:Undefined, Null, B ...

  2. 2018年第44周-scala入门-面向对象基础语法

    scala和java都是可以运行在JVM上, 所以scala和java是可以互相调用, 那么问题来了, 既然已经有java语言存在, 为什么还要发明scala语言. 存在即合理, 所以我就想找下sca ...

  3. python判断语法_Python基础语法——代码规范判断语句循环语句

    Python基础语法 代码的执行顺序 从上到下 从左到右 代码规范 模块名,包名,普通数据量一般小写字母,多个单词之间用 _ 连接 不要用系统定义的名称,具有特殊意义的表示符,如:doc,txt之类的 ...

  4. scala学习笔记-基础语法(1)

    Scala与Java的关系 Scala与Java的关系是非常紧密的!! 因为Scala是基于Java虚拟机,也就是JVM的一门编程语言.所有Scala的代码,都需要经过编译为字节码,然后交由Java虚 ...

  5. [PHP语法]PHP基础语法与数据类型

    基础语法: php是一门弱类型编程语言 在.php文件中php代码需要包含在<?php 和 ?> 之间,html可以和php混合编写 语句必须以;分号结束 变量名前面必须包含$,变量名可以 ...

  6. java 语法_Java基础语法

    标识符 定义 给包,类,方法,变量起名字的符号. 组成规则 标识符由字母.数字.下划线.美元符号组成. 命名原则:见名知意 包名:全部小写,多级包用.隔开. 举例:com.jourwon 类.接口:一 ...

  7. Python语法教程-基础语法01

    目录 1. Python应用 2. 在Linux中写python 3. Python基础语法 1. 注释 2. 变量定义及类型 3. 格式化输出 4. 用户输入 5. 运算符 6.数据转换 7. 判断 ...

  8. jsp java语法_JSP基础语法

    Java JSP 的 JSP基础语法 在本章中,我们将了解和学习JSP语法.并了解JSP开发涉及的简单语法(即元素)的基本用法. 为了方便演示,使用Eclipse创建一个动态Web项目:jspsynt ...

  9. python turtle基本语法_Python 基础语法-turtle篇

    Python 基础语法-turtle篇 今天这节课主要讲了类的概念,并引出turtle中的函数和Turtle类. -创建一个Turtle类:brad=turtle.Turtle() -定义Turtle ...

最新文章

  1. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16...
  2. Aizu - 1407 Parentheses Editor(对顶栈+模拟)
  3. web browser 发展史
  4. ZetCode Python 教程
  5. 【系统架构】大规模的C++项目代码层次结构
  6. 一道Struts面试题
  7. 安装SQL Server2008,要重启机器,解决办法
  8. 全网首发:Proguard加密后的getResource()问题
  9. JAVA 使用 pdfbox实现打印 PDF 文件 (横版,竖版)
  10. 第16课:迁移学习的模型训练
  11. web登录实现带php
  12. 鸢尾花数据集的线性多分类
  13. executeQuery、executeUpdate和execute
  14. 华为光猫HG8240的简单配置过程
  15. hadoop最新官网如何下载之前版本(2.7.1)
  16. “组件协作”模式----策略模式(Strategy Pattern)
  17. Keil MDK配置ARM开发环境
  18. 计算机丢失UxTheme无法修复,win7系统丢失uxtheme.dll怎么办,win7电脑uxtheme.dll丢失的解决方法...
  19. CAA开发之工程图---工程图开发自定义核心函数 1
  20. 四参数坐标转换c++_写给测绘新手,四参数与七参数坐标转换含义及区别

热门文章

  1. html5画图程序,基于HTML5的Windows画图程序
  2. linux桌面版安装输入法,Debian KDE桌面安装五笔和拼音输入法
  3. 【IDEA】IDEA的高级Debug技巧
  4. 【Linux】云服务器的购买与Linux远程连接
  5. 蓝桥杯真题 13省Cc1-猜年龄 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。 一次,他参加某个重要会议,年轻的脸孔引人注目。于
  6. nbu客户端卸载_在linux中卸载Netbackup
  7. Cisco RV340命令执行漏洞(CVE-2022-20707)及关联历史漏洞分析
  8. csr867x入门之spp使用(七)
  9. 新游戏中出现的基于BSP场景分割技术
  10. 高数笔记(十):定积分的概念与性质,微积分基本公式,牛顿-莱布尼兹公式,变限函数求导