初识Scala

1、Java与scala之间的共同之处

这里写图片描述
java与scala都是在jvm之上的语言。都需要编译成.class文件来执行,所以java的class文件scala是可以直接引用。

2、scala基础概念与书写注意事项

2.1 scala基础概念

**对象** - 对象有属性和行为。例如:一只狗的状属性有:颜色,名字,行为有:叫、跑、吃等。对象是一个类的实例。
**类** - 类是对象的抽象,而对象是类的具体实例。
**方法** - 方法描述的基本的行为,一个类可以包含多个方法。
**字段** - 每个对象都有它唯一的实例变量集合,即字段。对象的属性通过给字段赋值来创建。

2.2 scala书写基本注意信息

2.2.1 区分大小写
2.2.2 类名第一个字母大写,多个单词,每个单词首字母大写
2.2.3 方法名称首字母小写,多个单词,第二个单词开始首字母大写
2.2.4 程序文件名:程序文件名称应该与对象名称完全匹配
2.2.5 main(), def main(args: Array[String])--Scala程序从main()方法开始处理,程序入口。

2.3 scala注释方式

2.3.1 /*  */ 多行注释
2.3.2 // 单行注释

3、scala基本数据类型

3.1 数据类型介绍

3.1.1 整形
Byte 8位有符号补码整数。数值区间为 -128 到 127
Short 16位有符号补码整数。数值区间为 -32768 到 32767
Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
3.1.2 浮点型
Float 32位IEEE754单精度浮点数
Double 64位IEEE754单精度浮点数
3.1.3 字符型
Char 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
String 字符序列
3.1.4 布尔类型
Boolean true或false

3.2 Scala 基础字面量

3.2.1整形字面量
整型字面量用于 Int 类型,如果表示 Long,可以在数字后面添加 L 或者小写 l 作为后缀。
3.2.2 浮点型字面量
如果浮点数后面有f或者F后缀时,表示这是一个Float类型,否则就是一个Double类型的
3.2.3 布尔型字面量
true false
3.2.4 符号字面量
符号字面量被写成: ‘<标识符> ,这里 <标识符> 可以是任何字母或数字的标识(注意:不能以数字开头)。这种字面量被映射成预定义类scala.Symbol的实例。
如: 符号字面量 ‘x 是表达式 scala.Symbol(“x”) 的简写,符号字面量定义如下:

package scala
final case class Symbol private (name: String) {
   override def toString: String = "'" + name
}

3.2.5 字符字面量
在scala中字符类型表示为半角单引号(‘)中的字符:

'\u0041'
'\n'
'\t'    

//其中 \ 表示转移字符,其后可以跟 u0041 数字或者 \r\n 等固定的转义字符
3.2.6 字符串字面量
字符串表示方法是在双引号中(“) 包含一系列字符: “Hello,\nWorld!”
3.2.7 多行字符串的标识方法

'''
It is a new language!
Try your best!
'''

3.2.8 scala转义符
这里写图片描述

4、scala基本语法

4.1 常量、变量的定义

变量:
scala> var a1 = 1
a1: Int = 1
常量:(常量定义赋值后不可改变)
scala> val a2 = 1
a2: Int = 1
同时定义多个变量或者常量:

var age1, age2, age3 : Int = 22
println(age1)
println(age2)
println(age3)

4.2 tab快速补齐

// scala的快捷方式:tab(自动补全,或者跳出可选函数、方法)
scala> aa1.
%              &              *              +              -              
/              >              >=             >>             >>>            
^              asInstanceOf   isInstanceOf   toByte         toChar         
toDouble       toFloat        toInt          toLong         toShort        
toString       unary_+        unary_-        unary_~        |

4.3 导入库以及函数的使用

导入数学常用函数

scala> import scala.math._
import scala.math._

scala> max(22, 10)
res3: Int = 22

scala> min(9, 2)
res4: Int = 2

4.4 第一个scala程序

object HelloFirst {
  def main(args: Array[String]): Unit = {
    println("I't s a new world !")
  }
}

输出:

I't s a new world !
1 Object是Scala中的一个关键字,相当于java中的public static class这样的修饰符,也就是说Object中的成员都是静态的;
2 例子中的main方法是静态的,不需要实例化就可以被虚拟机调用,作为JVM平台上程序的入口的必备条件;
3 输入main使用快捷方式 ALT + / 可以快速补足main函数;
4 def是scala的关键字,所有使用def定义的内容都是函数或者方法;
5 args:Array[String]其中args是参数名称,Array[String]表面应用程序运行时候传入参数集合;
6 :Unit表明main入口方法的返回类型是Unit,也就是说执行main方法后返回的是Unit类型;
7 Unit是什么类型:相当于java中的Void类型;
8 = 是什么?是表明main方法执行的结果是由谁来赋值的,或者说main方法体在哪?在=的右面;
9 方法体一般使用{}来封装,里面可以有很多条语句;
10 {}语句默认情况下最后一条语句的结果类型就是{}的返回类型;
11 scala的println是借助了java的io操作,也就是说scala调用了java;
12 如果方法或者函数的类型或者返回类型是Unit的话就可以直接省略“:Unit = ”,其他非Unit值不可省略;
13 scala在实现底层经常会使用java的实现来缩短开发时间,例如:操作数据源(DB,NoSQL(HBase))的JDBC,再例如关于线程Thread的操作,scala旺旺也会直接使用java中的Thread;
14 按照当今OS的原理,程序的main入口方法都是运行在主线程中的,os的运行分为Kernel Space和User Space,应用程序是运行在User Space中,应用程序Scala所在的进程一般都是透过OS Fork出来,被Fork出来的应用程序进程默认会有主线程,而我们的main方法就是默认在主线程中的。

4.5 控制语句(if、for、while、break)

4.5.1 if

object Hello1 {
  def main(args: Array[String]):Unit = {
    println("It\'s My First Scala Project !")
    // if控制语句
    var age = 20
    var result = if (age < 18) "青少年" else "成年"
    println(result)

    // if表达式可以用在for循环等其他控制结构中用于限制结果
    println("if表达式可以用在for循环等其他控制结构中用于限制结果")
    for(i <- 0 to 10 if i % 2 == 0) {
      println("i = " + i + "可以被2整除!")
    }
  }
}

输出:

It's My First Scala Project !
成年
if表达式可以用在for循环等其他控制结构中用于限制结果
i = 0可以被2整除!
i = 2可以被2整除!
i = 4可以被2整除!
i = 6可以被2整除!
i = 8可以被2整除!
i = 10可以被2整除!

4.5.2 for
for循环是不断循环一个集合,然后for循环后面{。。。}代码块部分会根据for循环(…)里面提取的集合的item来作为{…}的输入作为流程控制。
2.1 for循环中加入的if叫做条件守卫,用于限制for循环(优化for循环,去掉不必要的执行步骤,或者说用于跳出for循环)
2.2 在for循环中可以提取什么内容取决于集合的类型!
2.3 想跳出for循环的话,除了加入if守卫以外,还可以使用return关键字。

object Hello2 {
  def main(args: Array[String]):Unit = {
    /* for循环是不断循环一个集合,然后for循环后面{...}代码块部分会根据for循环(...)里面提取的集合的item来作为{...}的输入作为流程控制*/
    var result2 = 0
    for(i <- 0.to(20)){
      result2 = result2 + i
    }
    println(result2)

    // 在for循环中可以提取什么内容取决于集合的类型
    for(i <- "Hello, Spark".split(" ")) println(i)

    // 想跳出for循环的话,除了加入if守卫以外,还可以使用return关键字
    for(i <- 1.to(20)){
      if(i == 3) return //return是返回的是方法级别的,这在实际开发中常用
      println(i)
    }
  }
}

输出

210
Hello,
Spark
1
2

4.5.3 while
While循环,也是循环集合来作为{…}的输入,进而完成流程的控制,while循环在实际Server和Framework开发中至关重要,例如一个线程一直继续下去,一般会使用while。

// while循环
    var flag = true
    for(i <- 1.to(10)){
      if(i % 3 == 2) flag = false
      while(flag){
      println("i = " + i)
      flag = false
    }
      flag = true
    }

输出:

i = 1
i = 3
i = 4
i = 6
i = 7
i = 9
i = 10

4.5.4 break
scala中要使用break首先要导入break

import scala.util.control.Breaks._

这里写图片描述

5、函数

函数暂时可以被简单的认为是包裹了一条或者几条语句的代码体,该代码体接收若干参数,经过代码体处理后返回结果,形成数学中的f(x) = x + 1
关于函数初级入门的几个要点:
* 1、def关键字来定义函数;
* 2、函数会自动进行类型推断来确定函数返回值的类型;如果函数名称和函数体之间没有等于号的话则类型推断失效,此时函数的返回值类型是Unit
* 3、函数的参数可以是类
* 4、如果在函数体中无法推倒出返回值类型,则需要制定返回值类型,例如费波纳茨序列(可能是Int也有可能是Long)
* 5、函数都是有返回值的,没有制定返回值类型的时候默认以最后一行值作为返回值类型;
* 6、默认参数,可以不指定参数,会自动指定一个默认值;
* 7、我们可以基于函数的参数名称来调整传入参数的顺序,重点在于为什么这么做?原因在于函数的背后其实是类,其参数就是类的成员,无所谓顺序;
* 8、函数如果不确定传递参数个数,可以使用变长参数的方式;传参时的一个方便的语法:1L to 5L: _*。
* 9、可变参数中的数据其实是可以被收集为数组Array数组,我们在入口函数main中其实就是可变参数,是以Array[String]的方式呈现的。

object HelloFunctionalProgramming {
  def main(args:Array[String]):Unit={
    helloWorld("Jerry", 20)
    println(helloWorld("Jerry", 20))

    // 带名参数,可以指定参数名称,而不需要根据定义的参数的位置进行定义
    helloWorld(age = 20, name = "aaa")

    println("-*" * 20)
    helloWorld2("Tom", 30)
    println(helloWorld2("Tom"))

    //fibonacci函数的调用
    println("fibonacci of 8 : " + fibonacci(8))

    // 可变参数调用
    println("sumAnyNum : " + sumAnyNum(1, 2, 3, 4, 5))
    println("sumAnyNum(1加到5) : " + sumAnyNum(1L to 5L: _*))
    println(sumRecursive(1 to 99: _*))
  }

  //定义一个两个参数函数
  def helloWorld(name : String, age : Int): Unit = {
    println("Hello, My name is " + name + " !")
    println("I'm " + age + " years old!")
  }

  // age : Int = 30默认参数,可以不传入age,默认赋予age = 30
  def helloWorld2(name : String, age : Int = 30) = {
    println("Hello, My name is" + name + " !")
    println("I'm " + age + " years old!")
    age
  }
  // 费波纳茨序列函数,递归调用
  def fibonacci(num : Int) : Long = {
    var result = 0
    if(num <= 2) 1
    else fibonacci(num - 2) + fibonacci(num - 1)
  }

  // 可变参数
  def sumAnyNum(num : Long*) = {
    var result = 0L
    for(each_num <- num){
      result = result.+(each_num)
    }
    result
  }

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

输出解析:

// 调用helloWorld("Jerry", 20)
helloWorld("Jerry", 20)
// 调用helloWorld("Jerry", 20) 函数都有返回值,没有指定则会给与一个Unit
println(helloWorld("Jerry", 20))

输出:
Hello, My name is Jerry !
I'm 20 years old!
Hello, My name is Jerry !
I'm 20 years old!
()
// 带名参数,可以指定参数名称,而不需要根据定义的参数的位置进行定义
helloWorld(age = 20, name = "aaa")
输出:
Hello, My name is aaa !
I'm 20 years old!
// 默认参数的调用,可以传入年龄,也可以不传入,默认30
helloWorld2("Tom", 30)
println(helloWorld2("Tom"))
输出:
Hello, My name isTom !
I'm 30 years old!
Hello, My name isTom !
I'm 30 years old!
30 
// 因为helloWorld2带有返回值,故会打印出来age 30
//fibonacci递归函数的调用
println("fibonacci of 8 : " + fibonacci(8))
输出:
fibonacci of 8 : 21
// fibonacci的定义中有指定返回值,原因是scala无法无法推倒其返回值,故不指定则会报错。
// 可变参数的调用
println("sumAnyNum : " + sumAnyNum(1, 2, 3, 4, 5))
println("sumAnyNum(1加到5) : " + sumAnyNum(1L to 5L: _*))
println(sumRecursive(1 to 99: _*)) // 递归求和
输出:
sumAnyNum : 15
sumAnyNum(1加到5) : 15
4950
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值