一、基础

REPL

什么叫REPL?

REPL是Read(读取)- Evaluate(求值)- Print(打印)-Loop(循环)。

是Scala解释器的一个过程。

输出

    println("Hello World")

声明值与变量、常量

1、变量用var表示,常量使用val表示

2、变量类型声明


var variableName : DateType [=Init Value] var x:String = "fonxian"

3、多个变量声明

var x,y = 100

4、元组


var x = ("x",18)

常用类型

scala不对基本数据类型包装数据类型做区分,这两种数据类型是由scala编译器完成的。

在REPL中,输入3.,按tab键,会出现方法的提示

3.toString()
    print(1.to(10))
println()
print(1 to 10)

结果输出

Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

调用函数和方法

import scala.math._
## 输出16.0
println(pow(2,4))

apply方法

两个语句等价

    // 输出o
println("Hello"(4))
println("Hello".apply(4))

二、控制结构和函数

五、访问限制符

访问限制符有public、private、protected,默认为public

被private修饰的成员只在包含该成员的类或对象中可见

练习题

题1:res变量是val还是var

res是val

题2:10 max 2 的含义是什么

表示 10.max(2)

元组

元组是不同类型值的聚集

//创建元组
val t = (1,2.5,'holy','shit')
//访问元组,访问第一个元素
t._1

函数

try 表达式


var result = try{
Integer.parseInt("dog")
}catch{
case _ => 0
}finally{
println("excute")
}

match 表达式

val code = 3
var result = code match{
case 1 => "one"
case 2 => "two"
case _ => "others"
}

求值策略

  • Call By Value

    • 对函数实参求值,且仅求值一次
  • Call By Name
    • 函数实参每次在函数体内被用到时都会求值

def foo(x:Int,y: => Int):Int={
x * x
} def loop():Int = loop

函数

(1)匿名函数

匿名函数定义格式 形参列表 => {函数体}

(2)柯里化函数

把具有多个参数的函数转换为一条函数链,每个节点上都是单一参数

例子1:


def add(x:Int)(y:Int) = x + y var add1 = add(1)_
add1(5) 等同于 add(1)(5) def add2 = add(2)_
add2(6)等同于add(2)(5)

例子2


def fun(f:Int => Int)(a:Int):Int={ f(a) } fun(x=>x*x)(5) //等同于 f(x) = x*x ;x = a;a=5;

(3)尾递归

覆盖当前记录,而不是在栈中创建新的函数


@annotation.tailrec
def fun(n:Int,m:Int):Int={
if(n <= 0) m
else fun(n-1,m*n)
} @annotation.tailrec
def fun1(n:Int,m:Int):Int={
if(n == 1) m
else fun(n-1,m+n)
}

例子1,计算f(x),a-b的求和

该例子涉及到的知识点有函数柯里化、尾递归


final def find(f:Int => Int)(a:Int)(b:Int):Int={ @annotation.tailrec
def loop(n:Int,acc:Int):Int={ if(n > b){
acc
}else{
loop(n+1,acc+f(n));
} } loop(a,0)
}

一、控制语句

var x = 40

if(x == 40){
println("greate")
}

二、循环

(1) 一般循环


while(a>1){ if(a==2){
break
}
a = a - 1
}

until x ,取到x以前的值

to x,取到值为x的值


for(i <- 0 until 10){
println(i)
} for(i <- 0 to 10){
println(i)
}

(2) for循环集合

for(x <- list){
println(x)
}

(3) for过滤


for(s<l;if s>0){
println(s)
}

(4) 使用分号设置多个区间,相当于多层for循环


for(a <- 1 to 3;b <- 1 to 3){
println("a:"+a)
println("b:"+b)
}

(5) for使用yield

for循环的返回值作为一个变量存储

var result = for{
s <- l
if(s > 0)
}yield s

一、List


var x = List(1,2,3,4)
//x:List[Int] = List(1, 2, 3, 4) var y = List("x","y","z")
//y: List[String] = List(x, y, z) 0 :: x
//res6: List[Int] = List(0, 1, 2, 3, 4) x ::: y
//List[Any] = List(1, 2, 3, 4, x, y, z) scala> "x"::"y"::"z"::Nil
res9: List[String] = List(x, y, z) x.head //获取第一个元素 x.tail //获取除第一个元素的其他元素 x.isEmpty //判断该列表是否为空

字符串转List


var a = "HelloWorld,2018"
//a: String = HelloWorld,2018 a.toList
//res0: List[Char] = List(H, e, l, l, o, W, o, r, l, d, ,, 2, 0, 1, 8)

filter函数

a.toList.filter(x => Character.isDigit(x))
res1: List[Char] = List(2, 0, 1, 8) //另一种简写方式 a.toList.filter(_.Character.isDigit(x))

takeWhile函数


a.toList.takeWhile(x => x!='d')
res2: List[Char] = List(H, e, l, l, o, W, o, r, l)

map函数


var a = List(1,2,3,4) a.map(x => x % 2 == 0)
a.map(_%2 == 0) var b = List(6,7,8) var p = List(a,b) a.map(_.filter(_%2 == 0))
//res14: List[List[Int]] = List(List(2, 4), List(8))

flatMap


a.flatMap(_.filter(_%2 == 0))
//res15: List[Int] = List(2, 4, 8)

reduce函数


a.reduce((x,y) => x+y) //等价于 a.reduce(_+_)

foldLeft函数


a.fold(0)((x,y) => x+y) //等价于 a.fold(0)(_+_)

二、Tuple元组

元组相当于数据库中的记录,可以放各种不同类型的值


val a = (1,2,3,4) a._1 //访问元组中第一个元素 a._2 //访问元组中第二个元素 val b = (1,"fzj","math",95)

例子1:返回一条记录,计算一个列表的元素个数、元素之和,元素的平方和


val a = (1,2,3,4) def sum(list:List[Int]):(Int,Int,Int)={
list.foldLeft(0,0,0)((x,y) => (x._1 + 1,x._2 + y,x._3 + y*y))
}

三、Set


var x = Set(1,2,3,4)

四、Map

(1) 创建Map


var x = Map("one" -> "1","two" -> "2") var x:Map[String,String] = Map()

(2) 添加key-value


x += ("three" -> "three")

(3) 合并

使用 ++运算符 或 Map.++()方法来连接两个Map


var colors = color1 ++ color2 var colors = color1.++(color2)

(4) 遍历


val sites = Map("one"->"one","two"->"two","three"->"three") sites.keys.foreach{
i =>
println("key="+i+",value="+sites(i))
}

1、HelloWorld

object HelloWorld{
def main(args:Array[String]):Unit={
println("hello,world")
}
}

编译并执行

scalac HelloWorld.scala
scala HelloWorld.scala

2、scala语法

scala末尾的分号是可选的,区分大小写,类名的第一个字母要大写,方法名第一个字母要小写

交互式编程

1 + 1
println("hello,world")

3、函数

def 方法名(参数名:类型):返回类型 = {

}

4、循环

4.1 输出[1 - n]

for(i <-  1 to n)

4.2 输出[1,n)

for(i <- 1 util n)

4.3 遍历数组

var a = Array("hello","world","fonxian")
for(i <- a){
println(i)
}

5、数组

5.1 新建数组

var a = new Array[Int](10)
var b = Array("hello","world","fonxian")

5.2 访问数组元素

a(1)

5.3 可变长度数组(等价于Java中ArrayList)

新建

var a = new ArrayBuffer[Int]()

添加元素

a += 1
a += (1,2,3,4)
a ++= ArrayBuffer(7,8,9)

数组操作

a.size
a.remove(2) //去掉索引值为2的元素
a.remove(2,3) //去掉以索引值为2的元素开始的3个元素
a.trimEnd(n) // 去掉尾部的n个元素
a.trimStart(n) //去掉头部的n个元素
a.insert(2,3) //索引值为2的位置插入一个元素

数组的一些循环操作

var result = for(elem <- a) yield 2*elem

等价于

for(elem <- a){
elem = elem *2
}
var result = for(elem <- a if elem % 2 == 0) yield 8 * elem

等价于

for(elem <- a){
if(elem % 2 == 0){
elem = elem * 8
}
}

6、映射

6.1 不可变映射,键对应的值不可以被改变

val scores = Map("feng" -> 100,"yun" -> 18)
val fengScore = scores("feng")

6.2 可变映射,键对应的值可以被改变

val myScores = scala.collection.mutable.Map("feng"->100,"yun"->18)
myScores("feng") = 1000

6.3 创建空的映射

val myScores1 = scala.collection.mutable.HashMap[String,Int]

6.4 添加元素

//添加元素
myScores1 += ((k,v))
myScores1 += (("aaa",1),("bbb",2))

6.5 获取映射元素的一种方法

//获取映射元素的一种方法
val omg = if(myScores1.contains("aaa")) myScores1("aaa") else 0

6.6 获取映射元素的另一种方法

//获取映射元素的另一种方法
val omg = myScores1.getOrElse("aaa",0)

6.7 删除一个映射元素

//删除一个映射元素
myScores1 -= "aaa"

6.8 遍历映射元素的key

//遍历映射元素的key
myScores1.keySet

6.9 遍历映射元素的value

//遍历映射元素的value
for(v <- myScores1.values){
println(v)
}

6.10 map+reduce

在经过map操作时,得到的是一个集合Vector(2,3,4,5),执行reduece操作时,得到5

val my = Vector(1,2,3,4)
my.map(n => n+1).reduce((a,b) => if(a>b) a else b)

泛型

定义一个泛型类

class StackTest[A] {
private var elements:List[A] = Nil
def push(x : A): Unit ={
elements = x::elements
}
def peek:A = elements.head
def pop():A = {
val currentTop = peek
elements = elements.tail
currentTop
}
}
object StackUse {

  def main(args: Array[String]): Unit = {

    val stack = new StackTest[Int]
stack.push(1)
stack.push(2)
println(stack.pop())
println(stack.pop()) val fruitStack = new StackTest[Fruit]
val apple = new Apple
val banana = new Banana fruitStack.push(apple)
fruitStack.push(banana) println(fruitStack.pop())
println(fruitStack.pop()) } } class Fruit
class Apple extends Fruit
class Banana extends Fruit

Scala出现的异常解决

Error:(21, 37) could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[flink.SensorReading]
val stream1 = env.fromCollection(list)

原因是少引入了包,引入包问题解决

import org.apache.flink.api.scala._

参考文档

《快学Scala》

Scala官方文档

Scala(一) —— 基础的更多相关文章

  1. Scala 语法基础

    一 简介 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性.Scala 运行在Java虚拟机上,并兼容现有的Java程序.Scal ...

  2. Scala零基础教学【1-20】

    基于王家林老师的Spark教程——共计111讲的<Scala零基础教学> 计划在9月24日内完成(中秋节假期之内) 目前18号初步学习到25讲,平均每天大约完成15讲,望各位监督. 初步计 ...

  3. Scala语言基础

    1. Scala语言的特点 a. 多范式编程语言,面向对象(抽象.封装)和函数式(过程.结果)编程 b. 代码简洁 ==>可读性较差 c. 代码会被变异成Java字节码,运行在JVM上 2. S ...

  4. Scala学习——基础篇

    [<快学Scala>笔记] 一.基础 1.变量val 标志符: 声明常量: 如,val answer = 1var 标志符:声明变量: 类型推断:变量的类型由scala根据初始化变量的表达 ...

  5. Scala编程基础

    Scala与Java的关系... 4 安装Scala. 4 Scala解释器的使用... 4 声明变量... 5 数据类型与操作符... 5 函数调用与apply()函数... 5 if表达式... ...

  6. scala的基础部分

    最近接触到spark,spark又是scala编写的,所以需要学习一下scala. scala是面向对象的,一切皆为对象, 数值,函数都是对象. println("Welcome to th ...

  7. 【scala】基础类型

    基础类型                              位数 Boolean                                 - Byte                 ...

  8. Scala实战高手****第2课:Scala零基础实战入门的第一堂课及如何成为Scala高手

    val声明的不可变的战略意义:1.函数式编程中要求值不可变,val天然符合这一特性:2.在分布式系统中,一般都要求值不可变,这样才能够要求分布式系统的设计和实现,同时拥有更高的效率,val声明的内容都 ...

  9. scala入门基础学习

    1.Scala基础语法 区分大小写 类名 - 对于所有的类名的第一个字母要大写.如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写. 方法名称 - 所有的方法名称的第一个字母用小写. ...

随机推荐

  1. 利用websocket实现微信二维码码扫码支付

    由于业务需要引入微信扫码支付,故利用websocket来实现消息推送技术. 实现大致流程:首先客户端点击微信支付按钮,触发微信支付接口,同时微信支付响应成功参数后,连接websocket客户端,此刻利 ...

  2. Go的Get命令兼容公司Gitlab仓库的HTTP协议

    对于公司的私有Gitlab仓库,没有对https支持,在使用最新版本的go get命令时,需要使用-insecure参数来支持http,但如果导入的包里边依赖了需要https的仓库,就不好使了,折腾了 ...

  3. 正确理解python中的赋值语句:a, b = b, a + b

    赋值语句: a, b = b, a + b 相当于: t = (b, a + b) # t是一个tuple a = t[0] b = t[1] 但不必显式写出临时变量t就可以赋值.

  4. 出错with root cause

    [背景:] 我自己写了一个项目,主页可以看到一个数据库里的一个应用的users用户表的所有数据,包括用户的年龄,姓名,出生日期等信息.后来又想再增加一个注册功能,写好了之后进行单元测试,结果就出现了w ...

  5. Ubuntu 16——安装——ns2.35和nam

    Ubuntu 16.04 安装ns2.35+nam 总结出以下安装步骤 1: 更新源 sudo apt-get update #更新源列表 sudo apt-get upgrade #更新已经安装的包 ...

  6. MapReduce实例学习

    https://blog.csdn.net/m0_37739193/article/details/77676859

  7. 用apache和tomcat搭建集群,实现负载均衡

    型的企业应用每天都需要承受巨大的访问量,在着巨大访问量的背后有数台服务器支撑着,如果一台服务器崩溃了,那么其他服务器可以使企业应用继续运行,用户对服务器的运作是透明化的,如何实现这种透明化呢?由如下问 ...

  8. 2018年3月24日上海MVP线下技术交流活动简报

    2018年3月24日下午,几位上海MVP自发组织了一次线下的技术交流会,主要由MVP胡浩牵头,我(陈晴阳).刘鑫.朱兴亮和胡浩各自做了一次主题演讲,具体主题是: 陈晴阳:<这还是我认识的Visu ...

  9. CLion之C++框架篇-优化框架,单元测试(二)

    背景   结合上一篇CLion之C++框架篇-安装工具,基础框架的搭建(一),继续进行框架优化!   googletest(GTest)是Google开源的C++测试框架,与CLion组合,对C++环 ...

  10. 组合拳出击-Self型XSS变废为宝

    前言 作者:米斯特安全攻防实验室-Vulkey_Chen 博客:gh0st.cn 这是一个鸡肋性质的研究,也许有些标题党,请见谅- 本文启发于一些讨论,和自己脑子里冒出来的想法. 组合拳搭配 Self ...