一、Scala 简介

1、Scala语言既可用于大规模应用程序开发,也可以用于脚本编程,2001年由Martin Odersk 开发,主要优势 速度和它的表达性。一门函数式编程语言,既有面向对象的特点,又有面向过程的特点。

2、Scala与Java关系:Scala代码需要经过编译为字节码,然后交由Java虚拟机来运行,可以任意调用就Java的代码。所以Scala也就是JVM的一门编程语言。

3、安装Scala版本:scala-2.11.8msi; 进入cmd 下输入scala,进入Scala编程;  scala -version 查看Scala版本

二、Scala基础

1、Scala解释器:进入安装Scala目录下——bin目录,运行scala.bat

scala解释器也被成为REPL(Read取值——Evalution求值——Print打印——Loop循环),会快速编译scala代码为字节码,然后交给JVM来执行。

在scala>命令行内,键入代码,解释器会直接返回结果,如果没有指定变量来存放这个值,那么值默认名称为res,而且会显示结果数据类型。

例:输入1+1,会看到res0:Int =2

内置变量:在后面还可以继续使用res这变量,以及它存放的值     例:“hi,”+res0,返回res2:String =hi,2

自动补全:在scala>命令行时,可以使用Tab键进行自动补全

2、声明变量

声明常量: val result=1+1   声明后无法改变它的值      例:result=3(报错)

声明变量:var  result=2,result=3    声明值可以改变引用    (建议使用val,在网络传输数据时,防止被错误的更改)

声明变量时,可以手动指定类型,也不可以不指定,scala会根据值进行类型推断,也可以将多个变量放在一起声明          例:val n1,n2 = 100                   val na1,na2:String = null

3、数据类型与操作符

基本数据类型:Byte、 Char、 Short、 Int、 Long、 Float、 Double、 Boolean。   (与Java不同的是首字母大写) scala数据类型统一都是类,scala自己负责基本数据类型与引用类型转换

使用以上类型, 直接就可以调用大量的函数, 例如, 1.toString(), 1.to(10) 结果是1到10 的一个集合

类型的加强版类型: Scala使用很多加强类给数据类型增加了上百种增强的功能或函数。

基本操作符: Scala的算术操作符与Java的算术操作符也没有什么区别, 比如+、 -、 *、 /、 %等, 以及&、 |、 ^、 >>、 <<等。

但是, 在Scala中, 这些操作符其实是数据类型的函数, 比如1 + 1, 可以写做1.+(1)

例如, 1.to(10), 又可以写做1 to 10

Scala中没有提供++、 --操作符, 我们只能使用+和-, 比如counter = 1, counter++是错误的, 必须写做counter += 1。

4、调用函数

除了方法之外,Scala还提供函数 ;import scala.math._ ,_是通配符,类似Java中的*

import scala.math._
sqrt(2)

三、控制结构、循环与函数

1、if表达式的定义: 在Scala中, if表达式是有值的, 就是if或者else中最后一行语句返回的值。

例如, val age = 30; if (age > 18) 1 else 0

可以将if表达式赋予一个变量, 例如, val isAdult = if (age > 18) 1 else 0

if表达式的类型推断: 由于if表达式是有值的, 而if和else子句的值类型可能不同,  此时Scala会自动进行推断, 取两个类型的公共父类型。
                             例:if(age > 18) 1 else 0, 表达式的类型是Int, 因为1和0都是Int

例:if(age > 18) "adult" else 0, 此时if和else的值分别是String和Int, 则表达式的值是Any, Any是String和Int的公共父类型

如果if后面没有跟else, 则默认else的值是Unit, 也用()表示, 类似于Java中的void或者null。  例如, val age = 12; if(age > 18) "adult"。 此时就相当于if(age > 18) "adult" else ()
       将if语句放在多行中: 默认情况下, REPL只能解释一行语句, 但是if表达式通常需要放在多行。     可以使用{}的方式, 比如以下方式, 或者使用:paste和ctrl+D的方式。
                             例:

if(age > 18) { "adult"
} else if(age > 12) "teenager" else "children"

 2、语句终结符、块表达式

默认情况下, Scala不需要语句终结符, 默认将每一行作为一个语句

一行放多条语句: 如果一行要放多条语句, 则必须使用语句终结符           例如, 使用分号作为语句终结符, var a, b, c = 0; if(a < 10) { b = b + 1; c = c + 1 }

对于多行语句, 还是会使用花括号的方式

块表达式: 块表达式, 指的就是{}中的值, 其中可以包含多条语句, 最后一个语句的值就 是块表达式的返回值。 例val d= if(a>10){"a";"b"} 返回的是b

3、输入输出

print和println: print打印时不会加换行符, 而println打印时会加一个换行符。

printf: printf可以用于进行格式化      例如, printf("Hi, my name is %s, I'm %d years old.\n", "Leo", 30)
      readLine: readLine允许我们从控制台读取用户输入的数据, 类似于Java    中的System.in和Scanner的作用。

输入输出案例:

val name = readLine("Welcome to Game House. Please tell me your name: ")
print("Thanks. Then please tell me your age: ")
val age = readInt()
if(age > 18) {
printf("Hi, %s, you are %d years old, so you are legel to come here!", name, age)
} else {
printf("Sorry, boy, %s, you are only %d years old. you are illegal to come here!",
name, age)
}

 4、循环

(1)Scala拥有与Java相同的while和do-while循环  ,但没有与for(初始化变量;判断条件;更新变量)循环直接对应的对构  ,Scala中的for: for(i<-表达式),让变量i遍历<-右边表达式的所有值。

注意:在for循环的变量之前并没有val或var的指定,该变量的类型是集合的 元素类型。    循环变量的作用域一直持续到循环结束。
        (2)until方法返加一个不包含上限的区间   var sum =0;for(i<-0 until 10) sum+=i                 区间是0到9,不包含10

直接遍历 val content="hello";for(c<- content) print(c+" ")

(3)可以变量<-表达式的形式提供多个生成器,用分号将它们隔开    例:for(i<-1 to 3;j<- 1 to 3)print((10*i+j)+" ")

for循环中添加过滤条件if语句,即为守卫式。       例:for(i<-1 to 3;j<- 1 to 3 if i !=j)print((10*i+j)+" ")

(4)在循环中使用变量    例:for(i<-1 to 3;from =4-i;j<-from to 3) print((10*i+j)+" ")

推导式:如果for循环的循环体以yield开始,则该循环会构造出一个   集合,每次迭代生成集合中的一个值。

例:for(i<- 1 to 10) yield i%3     生成Vector(1,2,0,1,2,0,1,2,0,1)
    5、(1)高级for循环

多重for循环: 九九乘法表

for(i <- 1 to 9; j <- 1 to 9) {
if(j == 9) {
println(i * j)
} else {
print(i * j + " ")
}
}

           if守卫: 取偶数   for(i <- 1 to 100 if i % 2 == 0) println(i)
               for推导式: 构造集合    for(i <- 1 to 10) yield i

(2)在代码块中定义包含多行语句的函数体

单行函数:def a(name:String) =print("hello,"+name)

如果函数体中有多行代码, 则可以使用代码块的方式包裹多行代码, 代码块中最后一行的  返回值就是整个函数的返回值。 与Java中不同, 不是使用return返回值的。

def sum(n: Int) :Int= {
var sum = 0
for(i <- 1 to n) sum += i
sum
}

      :Int返回值的类型

(3)函数的定义与调用

在Scala中定义函数时, 需要定义函数的函数名、 参数、 函数体

Scala要求必须给出所有参数的类型, 但是不一定给出函数返回值的类型。    只要右侧的函数体中不包含递归的语句, Scala就可以自己根据右侧的表达式推断出返回类型。

def sayHello(name: String, age: Int) = {
if (age > 18) { printf("hi %s, you are a big boy\n", name); age }
else { printf("hi %s, you are a little boy\n", name); age
} s
ayHello("leo", 30)

  (4)递归函数与返回类型

如果在函数体内递归调用函数自身, 则必须给出函数的返回类型 。   例如实现经典的斐波那契数列: 9 + 8; 8 + 7 + 7 + 6; 7 + 6 + 6 + 5 + 6 + 5 + 5 + 4; ....

def fab(n: Int): Int = {
if(n <= 2) 1
else fab(n - 1) + fab(n - 2)
}

   (5)默认参数

在Scala中, 有时我们调用某些函数时, 不希望给出参数的具体值, 而希望使  用参数自身默认的值, 此时就定义在定义函数时使用默认参数。 如果给出的参数不够, 则会从左往右依次应用参数。
         例:def sayHello(firstName: String, middleName: String = "William", lastName: String = "Croft") = firstName + " " + middleName + " " + lastName 
        (6)Java与Scala实现默认参数的区别

Java:

public void sayHello(String name, int age) {
if(name == null) {
name = "defaultName"
} if
(age == 0) {
age = 18
}
} s
ayHello(null, 0)

       scala:

def sayHello(name: String, age: Int = 20) {
print("Hello, " + name + ", your age is " + age)
} s
ayHello("leo")

   (7)带名参数

在调用函数时, 也可以不按照函数定义的参数顺序来传递参数, 而是使用带名参数的方式来 传递。

sayHello(firstName = "Mick", lastName = "Nina", middleName = "Jack")
            还可以混合使用未命名参数和带名参数, 但是未命名参数必须排在带名参数前面。
             sayHello("Mick", lastName = "Nina", middleName = "Jack")
       (8)使用序列调用变长参数

在如果要将一个已有的序列直接调用变长参数函数, 是不对的。 比如val s = sum(1 to 5)。 此时需要使用Scala特殊的语法将参数定义为序列, 让Scala解释器能够识别。
              val s = sum(1 to 5: _*) 通过 :_*转换成参数序列
            例:使用递归函数实现累加

def sum2(nums: Int*): Int = {
if (nums.length == 0) 0
else nums.head + sum2(nums.tail: _*)
}

          Int* :变长参数(参数长度可变)      head取出集合第一个元素     tail 取出第一个剩下的元素

6、函数——过程、 lazy值和异常

过程:在Scala中, 定义函数时, 如果函数体直接包裹在了花括号里面, 而没有使用=连接,  则函数的返回值类型就是Unit, 这样的函数就被称之为过程。  过程通常用于不需要返回值的函数。
 过程还有一种写法, 就是将函数的返回值类型定义为Unit。
                     例:def sayHello(name: String) = "Hello, " + name
                          def sayHello(name: String) { print("Hello, " + name); "Hello, " + name }
                          def sayHello(name: String): Unit = "Hello, " + name

lazy:在Scala中, 提供了lazy值的特性, 也就是说, 如果将一个变量声明为lazy, 则只有在第一次使用  该变量时, 变量对应的表达式才会发生计算。 这种特性对于特别耗时的计算操作特别有用,

比如打开文件进行IO, 进行网络IO等。

import scala.io.Source._
                    lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString
                   即使文件不存在, 也不会报错, 只有第一次使用变量时会报错, 证明了表达式计算的lazy特性。

val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString 与lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString的比较

lazy声明的这行代码并没有被执行,当调用lines时才被执行,lazy是spark scala中很重要的特性

异常:在Scala中, 异常处理和捕获机制与Java是非常相似的。

例:

try {
throw new IllegalArgumentException("x should not be negative")
} catch {
case _: IllegalArgumentException => println("Illegal Argument!")
} finally {
print("release resources!")
}

  或者

try {
throw new IOException("user defined exception")
} catch {
case e1: IllegalArgumentException => println("illegal argument")
case e2: IOException => println("io exception")
}

四、数组

1、数组

若长度固定使用Array,若长度不固定则使用ArrayBuffer

定长数组  val nums=new Array[Int](10); //10个整数的数组      或者    val str =Array("hello","world")

String 默认值是null   Int默认值0  Boolean 默认值 是false   ,取值时 数组用(),JAVA用[]

2、变长数组:数组缓冲

对于那种长度按需要变化的数组,Java有ArrayList,Scala有 ArrayBuffer

例:val arr=ArrayBuffer[Int]()                 先导入包 scala.collection.mutable.ArrayBuffer

arr +=1                           添加元素

arr++=Array(5,3,2)          添加元素

arr.trimEnd(5)                删除从后往前数5个

arr.insert(2,6)              第一个代表索引,剩下为添加的元素(在第三个数前添加6)

arr.remove(2,3)           第一个代表索引,第二个是个数(移除三个数,从第三个开始依次往后)

3、变长数组与定长数组之间的转换

变长数组→定长数组:.toArray                 定长数组→变长数组:.toBuffer        对原数组没有影响,只是构建新的集合

4、遍历数组

for(i<-0 until arr.length) print(arr(i)+" ")

for(i<-(0 until arr.length).reverse)  print(arr(i)+" ")        数组中的元素从后往前依次输出

for (i<-0 until (arr.length,2)) print(arr(i)+" ")              跳跃输出,长度为2,例:原数组  (1,2,3,4,5)   结果(1,3,5)

5、数组常用算法

arr.sum    求和                   arr.max   求最大值          arr.min  最小值

val  arrs=arr.sorted    对arr数组进行排序

val  arrs=arr.sortWith(_>_)        降序排序

val  arrs=arr.sortwith(_<_)        升序排序

arrs.mkString("and")       arrs.mkString("&&")    mkString方法允许指定元素之间的分隔符

五、补充
     
1、接口在scala中不存在, 函数存在不依赖类,方法依赖于类
       2、实现直接三角形

for(i<-1 to 5;temp=2*i-1;j<-1 to temp){
print("*")
if(j==temp)println()
}

  3、递归函数:自身调用自身       

def fn(n:Int):Int{
if(n>0&&n<=1) 1
else n*fn(n-1)
}

  4、十进制转换成二进制

十进制6转换成二进制,6除以2等3余0 ,3除以2等1余1,1除以2等0余1,所以转换成二进制是 00000110 (总共8位,余数倒着来)

     5、面向对象三大特性

 

scala(一)的更多相关文章

  1. jdb调试scala代码的简单介绍

    在linux调试C/C++的代码需要通过gdb,调试java代码呢?那就需要用到jdb工具了.关于jdb的用法在网上大家都可以找到相应的文章,但是对scala进行调试的就比较少了.其实调试的大致流程都 ...

  2. scala练习题1 基础知识

    1, 在scala REPL中输入3. 然后按下tab键,有哪些方法可以被调用? 24个方法可以被调用, 8个基本类型: 基本的操作符, 等:     2,在scala REPL中,计算3的平方根,然 ...

  3. 牛顿法求平方根 scala

    你任说1个整数x,我任猜它的平方根为y,如果不对或精度不够准确,那我令y = (y+x/y)/2.如此循环反复下去,y就会无限逼近x的平方根.scala代码牛顿智商太高了println( sqr(10 ...

  4. Scala集合和Java集合对应转换关系

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用Scala编码的时候,经常会遇到scala集合和Java集合互相转换的case,特意mark一 ...

  5. Scala化规则引擎

    1. 引言 什么是规则引擎 一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑.业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技 ...

  6. Scala快速概览

    IDEA工具安装及scala基本操作 目录 一. 1. 2. 3. 4. 二. 1. 2. 3. 三. 1. 2. 3. 4. 5. 6. 7. 四. 1. (1) (2) (3) (4) (5) ( ...

  7. Scala Macros - scalamela 1.x,inline-meta annotations

    在上期讨论中我们介绍了Scala Macros,它可以说是工具库编程人员不可或缺的编程手段,可以实现编译器在编译源代码时对源代码进行的修改.扩展和替换,如此可以对用户屏蔽工具库复杂的内部细节,使他们可 ...

  8. Scala Macros - 元编程 Metaprogramming with Def Macros

    Scala Macros对scala函数库编程人员来说是一项不可或缺的编程工具,可以通过它来解决一些用普通编程或者类层次编程(type level programming)都无法解决的问题,这是因为S ...

  9. Scala Reflection - Mirrors,ClassTag,TypeTag and WeakTypeTag

    反射reflection是程序对自身的检查.验证甚至代码修改功能.反射可以通过它的Reify功能来实时自动构建生成静态的Scala实例如:类(class).方法(method).表达式(express ...

  10. Scala For Java的一些参考

          变量 String yourPast = "Good Java Programmer"; val yourPast : String = "Good Java ...

随机推荐

  1. Qt-QML-Canvas-雷达扫描仪表简单

    使用QML实现的雷达仪表的实现,主要实现了余晖扫描的实现,其他的还是比较简单的,后面可能会加入目标标识,目前的功能仅仅是一个假的扫描雷达 来看代码 /* 作者:张建伟 时间:2018年4月27日 简述 ...

  2. 【jpeg_Class 类】使用说明

    jpeg_Class类是针对图片操作类,可以获取图片属性.等比例缩略图片.裁切图片.图片上打印文字及打印水印等功能. 目录 原型 参数 返回 说明 Sub load(byVal path) path ...

  3. 使用performance进行前端性能监控

    该文章仅作为自己的总结 1.performance.timing对象 navigationStart:当前浏览器窗口的前一个网页关闭,发生unload事件时的Unix毫秒时间戳.如果没有前一个网页,则 ...

  4. HPUX修改disk实例号--11.31only

    有时由于一些原因或者用户的要求,需要修改Disk的实例号,这里简单介绍如何手工进行修改. 在修改之前需要做一些准备工作,即先将stale状态的设备文件清理掉,具体步骤如下: 使用ioscan命令列出s ...

  5. linux 下 mysql安装和配置

    最近在学习R语言,看到R与数据库交互这一部分,就自己动手实践了一下,数据库选择的是mysql,主要记录下linux下怎么安装mysql. 网上的很多资料都有相关的文章,这里只是记录下自己安装过程中遇到 ...

  6. DevOps之六 shell以及pipeline 命令部署

    一 使用shell命启动spring boot 项目 1. 使用shell停止当前项目 #!/bin/sh main() { clear pid=`ps -ef|grep xx.jar|grep -v ...

  7. PKI(Public Key Infrastucture)介绍

    PKI(Public Key Infrastucture)介绍 根据Wikipedia PKI词条整理. PKI(Public Key Infrastucture)是一系列的规则.策略以及过程,可以用 ...

  8. spark的运行方式——转载

    本文转载自:      spark的运行方式 本文主要讲述运行spark程序的几种方式,包括:本地测试.提交到集群运行.交互式运行 等. 在以下几种执行spark程序的方式中,都请注意master的设 ...

  9. WIN 7 发布项目

    本人工作都快两年了不知道web 怎么发布 今天我自己非常恼火!我就暗暗研究.希望能给新手指导 准备工作:WIN7 系统 .IIS 6.0.MVC (vs 新建mvc项目自带的项目) OK begin ...

  10. Thunder团队Final周贡献分分配结果

    小组名称:Thunder 项目名称:爱阅app 组长:王航 成员:李传康.翟宇豪.邹双黛.苗威.宋雨.胡佑蓉.杨梓瑞 分配规则 则1:基础分,拿出总分的20%(8分)进行均分,剩下的80%(32分)用 ...