• 为什么要学习scala?
  • 什么是scala?
  • 实战初级scala

唯一的目的就是:能够看懂Spark源码;
学习新的一门编程语言(第二门):是很快的;(类比着学,所有的编程语言都是思路相通的)只不过语法不一样;

  • 编程语言:java,php,.net,c++,scala,python
  • 因为所有的编程语言只是发送指令,电脑干活;电脑都是由一堆的硬件组成;(电路板);只认二进制数据(0,1);电脑只识别:二进制语言;人类的语言电脑听不懂;(才有了操作系统做为翻译);编程语言相当于各个领域;
  • 世界上有各种各样的语言;中国人说汉语,法国人说法语;他们两个人之间是无法沟通的,得需要找一个懂英语的人,翻译(英语是世界通用语言);人类学习母语是很累的,但是再学习第二语言是很快的;不同的语言描述的都是同一个事物,只不过有不同的叫法而已
  • 门门通,不如一门精;你学习好一门编程语言(学精);如果将来的系统需要用到其它的编程,你放心,肯定会有这门编程语言的高手也与你对接;(接口)通过网络传输,传输的内容是json;

1.介绍scala

Scala:它不是一门新的编程语言,而是一个结合体;
scala要想运行,必须安装jdk;它的编译和运行在jdk基础之上;(scala就是java的一个框架而已)
它的语法和javascript很像; 一个方法的参数类型居然还可以是方法;(函数编程)(和lambda表达式的思想很
像)

官网:https://www.scala-lang.org/;它都会有一段话来描述一下这个xx是什么东东;

文档:https://docs.scala-lang.org/


2.入门

1)在scala中,类型可是方法;在java中类型(基本数据类型和引用类型;在javascript中类型又多了一个function;scala就是把javascript和java结合起来)。
2)要定义一个变量,或者准备要使用一个类型,必须定义变量是什么类型;(强类型语言);scala是一个弱类型语言(变量不需要指定类型);javascript也是一个弱类型语言。
3)java文件和scala文件都是编译成class文件;在java文件中定义的类,在scala可以使用,反过来也是可以的;

可以直接在浏览器上码scala代码;
打开:https://scalafiddle.io
在左侧窗格中粘贴println(“Hello, world!”)

代码块:直接用大括号括起来,代码块
函数和方法类似,但是两个不相等;
方法是被def修饰,
函数是木有被def修饰
剩下的都一样

3.名词介绍

Java Scala
Interface traits
枚举 Case class

4.统一类型

Scala:的类型有哪些,scala写变量的时候不需要写类型(人家自己推断,你可以省略也可以加上)

1.Any是所有类型的超类型,也称为顶级类 型。它定义了一些通用的方法如equals、hashCode和toString。Any有两个直接子类:AnyVal和AnyRef。
2.AnyVal代表值类型。有9个预定义的非空的值类型分别是:Double、Float、Long、Int、Short、Byte、Char、Unit和Boolean。Unit是不带任何意义的值类型,它仅有一个实例可以像这样声明:()。所有的函数必须有返回,所以说有时候Unit也是有用的返回类型。
3.AnyRef代表引用类型。所有非值类型都被定义为引用类型。在Scala中,每个用户自定义的类型都是AnyRef的子类型。如果Scala被应用在Java的运行环境中,AnyRef相当于java.lang.Object。
4.Nothing和Null
4.1.Nothing是所有类型的子类型,也称为底部类型。没有一个值是Nothing类型的。它的用途之一是给出非正常终止的信号,如抛出异常、程序退出或者一个无限循环(可以理解为它是一个不对值进行定义的表达式的类型,或者是一个不能正常返回的方法)。
4.2.Null是所有引用类型的子类型(即AnyRef的任意子类型)。它有一个单例值由关键字null所定义。Null主要是使得Scala满足和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍null的替代方案。

5.类

Scala中的类是用于创建对象的蓝图,其中包含了方法、常量、变量、类型、对象、特质、类,这些统称为成员。类型、对象和特质将在后面的文章中介绍。

6.特质

特质 (Traits) 用于在类 (Class)之间共享程序接口 (Interface)和字段 (Fields)。 它们类似于Java 8的接口。 类和对象 (Objects)可以扩展特质,但是特质不能被实例化,因此特质没有参数。

7.元组

1)Map:是一个集合,集合中的每一个元素都有key和value(共两个);
2)元组也是一个集合,集合中的每一个元素都有22值
3)在 Scala 中,元组是一个可以容纳不同类型元素的类。 元组是不可变的。
4)当我们需要从函数返回多个值时,元组会派上用场。
5)Scala 中的元组包含一系列类:Tuple2,Tuple3等,直到 Tuple22。 因此,当我们创建一个包含 n 个元素(n 位于 2 和 22 之间)的元组时,Scala 基本上就是从上述的一组类中实例化 一个相对应的类,使用组成元素的类型进行参数化。

8. 混编–mixin

/* 这是一个抽象类 */
abstract class A {val message: String
}
/* 这是一个类,实现了抽象类A */
class B extends A {val message = "I'm an instance of class B"
}
/* 这是一个特质,居然还可以继承自一个抽象类 */
trait C extends A {def loudMessage = message.toUpperCase()
}
/* 一个类实现一个接口使用extends; 如果这个类有父类(使用extends);接口要换成with*/
class D extends B with Cval d = new D
println(d.message)  // I'm an instance of class B
println(d.loudMessage)  // I'M AN INSTANCE OF CLASS B

9.高阶函数

1)高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。在Scala中函数是“一等公民”,所以允许定义高阶函数。这里的术语可能有点让人困惑,我们约定,使用函数值作为参数,或者返回值为函数值的“函数”和“方法”,均称之为“高阶函数”。
2)说白了:就是方法的参数或者返回值,居然还可以是一个函数(高阶函数)
3)既然Scala编译器已经知道了参数的类型(一个单独的Int),你可以只给出函数的右半部分,不过需要使用_代替参数名(在上一个例子中是x)

10.柯里化

方法可以定义多个参数列表,当使用较少的参数列表调用多参数列表的方法时,会产生一个新的函数,该函数接收剩余的参数列表作为其参数。这被称为柯里化。

/* scala中是可以方法套用方法* 方法定时的时候有两个参数列表;* * 类似于:方法的重载*  */def fun3(a:Int)(c:Int,b:Int) :Unit ={println("---a--" + a);println("---b--" + b);print("---c--" + c);}/* 调用方法 */fun3(2)(3,4);/* 第一步 fun3(2)(3,4)* fun4==fun3(30)* 第二步* fun4(40,50)*             使用一个方法进行了替代(3,4)* _表示省略后面的形参列表;* * 柯里化:*  */def fun4 = fun3(30)_;/* 调用方法 */fun4(40,50);

11.隐藏参数

1)隐式(IMPLICIT)参数
如果要指定参数列表中的某些参数为隐式(implicit),应该使用多参数列表。例如:
def execute(arg: Int)(implicit ec: ExecutionContext) = ???
2)方法可以具有 隐式 参数列表,由参数列表开头的 implicit 关键字标记。 如果参数列表中的参数没有像往常一样传递, Scala 将查看它是否可以获得正确类型的隐式值,如果可以,则自动传递。
3)Scala 将查找这些参数的位置分为两类:
Scala 在调用包含有隐式参数块的方法时,将首先查找可以直接访问的隐式定义和隐式参数 (无前缀)。
然后,它在所有伴生对象中查找与隐式候选类型相关的有隐式标记的成员。
4)更加详细的关于 Scala 到哪里查找隐式参数的指南请参考 常见问题
5)在下面的例子中,我们定义了一个方法 sum,它使用 Monoid 类的 add 和 unit 方法计算一个列表中元素的总和。 请注意,隐式值不能是顶级值。

/* 定义了一个抽象类 */
abstract class Monoid[A] {/* 把两个参数相加,得到一个返回值(通过方法名判断出来) */def add(x: A, y: A): A/* 定义一个变量,unit:木有返回值 */def unit: A
}/* object:单例的对象 */
object ImplicitTest {/* 创建了一个string类型的对象 */implicit val stringMonoid: Monoid[String] = new Monoid[String] {/* 对这里面的两个方法做了实现;java.lang.String这个类里面有一个方法叫concat */def add(x: String, y: String): String = x concat ydef unit: String = ""}/* 创建了一个int类型的对象 */implicit val intMonoid: Monoid[Int] = new Monoid[Int] {/* 对这里面的两个方法做了实现 */def add(x: Int, y: Int): Int = x + ydef unit: Int = 0}/* 参数是一个List,我们在定义方法的时候无法知道这个List里面放的是什么类型要想知道List里面放的是什么类型,只有在调用方法的时候才会知道如何知道在调用方法的时候,如果List里面放的是Int,就默认的调用intMonoid如果List里面放的是String,就默认的调用stringMonoid要想实现这一个效果,就得加上implicit;(隐式参数)*/def sum[A](xs: List[A])(implicit m: Monoid[A]): A =if (xs.isEmpty) m.unitelse m.add(xs.head, sum(xs.tail))def main(args: Array[String]): Unit = {/* 这个List里面放的是int */println(sum(List(1, 2, 3)))       // uses IntMonoid implicitly/* 这个List里面放的是String */println(sum(List("a", "b", "c"))) // uses StringMonoid implicitly}
}

12.实战scala初级

标准的HelloWorld:

package com.jinghangzz.scala/*** scala的HelloWorld*/
object HelloWorld {/*** def:(修饰符)* main:方法名* 形参:变量:类型* Unit:void,此方法木有返回值*/def main(args: Array[String]): Unit = {/* 两种写法* scala中特有的写法;可以省略掉* System.out.println* 就是在写scala代码的时候,每一行结束的时候分号可写可不写(建议写上)*  */println("==南宋四大名将==")/* 是java的写法;* java和scala通用*  */System.out.println("==岳飞,韩世忠,刘光世,张俊==");}
}

简化版本的HelloWorld

package com.jinghangzz.scala/*** 是HelloWorld的简化版本* 省掉main方法*/
object HwApp extends App {println("==岳飞,韩世忠,刘光世,张俊==");
}

概览

package com.jinghangzz.scala/*** 基础知识*       变量(主要)和常量*      变量有三个要素:类型,名字值;*                类型有哪些:*                 名字:(标识符)*               值:讲类型的时候,已经讲过了每一个类型的取值范围*       在定义方法的时候,如果是def修饰的方法,=后面不能跟上>,*                 如果是在定义一个函数funtion,后面得跟上>*/
object Base {def main(args: Array[String]): Unit = {println("==宋太祖:(赵匡胤)==");/** java代码:int i = 0 ; (变量三要素)* */var i = 10 println("i====" + i );var j = 20 ; println("j====" + j );j = 30 ; println("j====" + j );/* 10 + 30 = 40  */println("i + j = " + (i + j )) ; /** 常量:final i = 0 ; * val:常量 不能修改值* */val z = 0 ; /* 最全的写法* var 变量名:类型 = 值*  */var a:Int = 10 ; /* 函数:方法;五要素* 修饰符,方法名,形参,方法体;返回值* * 木有名字;匿名函数*  *///(a:Int,b:Int) => {a + b} ; /* 函数起了一个名字* 先定义方法,再拿一个变量接收,这个写法和javascript一样* * 在java中,最外层是类,第一层:属性和方法;是否允许有第三层也是方法;(方法绝对不可以套方法)* 而scala允许方法调用方法*  */var fun1 = (a:Int,b:Int) => {a + b}/* 上面的写法和下面的写法一样 */def fun2(a:Int,b:Int) :Int = {a + b}/* 调用函数 */var result = fun1(10,30);println("==结果==" + result);/* scala中是可以方法套用方法* 方法定时的时候有两个参数列表;* * 类似于:方法的重载*  */def fun3(a:Int)(c:Int,b:Int) :Unit ={println("---a--" + a);println("---b--" + b);print("---c--" + c);}/* 调用方法 */fun3(2)(3,4);/* 第一步 fun3(2)(3,4)* fun4==fun3(30)* 第二步* fun4(40,50)*           使用一个方法进行了替代(3,4)* _表示省略后面的形参列表;* * 柯里化:*  */def fun4 = fun3(30)_;/* 调用方法 */fun4(40,50);/* 所有的代码都可以省略 * 如果方法的形参木有,小括号可以省略* 如果方法木有返回值,那么方法名后面跟的是:返回值可以省略* 如果大括号(方法体)只有一行,那大括号可以省略* */def fun5 = println("a + b ===== 测试一下");/* 调用* 如果方法木有形参,小括号可以省略*  */fun5;/* ========创建一个对象======== */var p1 = new Person(23,"赵匡胤");println("==toString==" + p1.toString())/* 调用方法 */p1.sayvar p2:Person = new Person(24,"赵匡义");p2.say/* 类比较的是栈的上值 */println("p1 == p2===" + (p1 == p2) )/* 创建案例类 */var po1 = Point(3,4)var po2 = Point(3,4);println("==po1==" + po1.toString())/* 案例类默认已经重写了equals方法,它比较的就是值 */println("po1 == po2===" + (po1 == po2) )/* object调用方法*  object使用的时候可以不用new对象*  */IdFactory.create ; IdFactory.create ; }
}/* 创建一个新的类* 后面可以直接跟上属性,这叫构造方法*  */
class Person(age:Int,name:String)
{/*** 说话的方法* def say() :Unit = {}*/def say = println(this.age + "===say==" + this.name)
}/* * 样例类:(Case Class)* 样例类一般不用于可变的对象,并且可以做值比较(只有四类八种基本数据类型;==)* 样例类可以不用new来创建对象* 样例类:toString:默认就是构造方法,同时把值带上了* Point(点)*/
case class Point(x:Int,y:Int)/**
object;对象的意思 ,
默认就是单例;一个jvm只能有一个java对象
*/
object IdFactory
{var i:Int = 0 ; /*** 方法*/def create = {println("i的值:" + i );/* 自加1 */i = i + 1  ; }
}

特质(接口)

package com.jinghangzz.scala/*** 特质:接口*/
object TraitTest {def main(args: Array[String]): Unit = {println("==赵光义(宋太宗)==赵炅")/* 创建对象 */var p1 = new Per;p1.eatp1.sleep/* 创建一个男人 */var m:Man = new Man();m.eat();m.sleep;}
}/*** 定义一个接口*/
trait IAdmin
{/* 抽象方法 */def eat():Unit ;/* 抽象方法 */def sleep;
}/*** 一个类实现一个接口,要重写接口中所有的方法*/
class Per extends IAdmin {def eat(): Unit = {println("=Per==eat=");}def sleep: Unit = {println("=Per==sleep=");}
}/*** 写一个男人,继承自Per*/
class Man extends Per
{/* 对父类的方法不满意,要重写* 必须加上override*  */override def eat() :Unit ={println("==Maneat==");}
}

13.统一类型+类的代码

package com.jinghangzz.scala/*** 基础类型*/
object BaseValue {def main(args: Array[String]): Unit = {println("==aa==");/* 调用方法 *///base_01//base_02base_03}/*** 统一类型*/def base_01 {/* 定义一个List */var list = List(1,"a","b",true,() =>{} );/* * foreach:这个方法有一个参数;这个参数的类型是函数;* java中:方法的参数是接口,而且接口只一个抽象方法;(lambda表达式的前题条件)* foreach:方法的参数是函数;目前做的工作是调用;* 提示:f: Any => U;函数有一个参数,木有返回值*  */list.foreach( t => println("==循环=:" + t) );}/*** 类*/def base_02 {/* 定义一个类* 属性后面直接跟值:表示默认值* * 不带val或var的参数是私有的,仅在类中可见。*  */class Person(var age:Int = 24,var name:String){/* 私有的属性,是为了提供读写器 */private var _weight:Int = 0 ;/* get方法 */def weight = _weight ; /* set方法* 注意下对于setter方法的特殊语法:这个方法在getter方法的后面加上_=,后面跟着参数*  */def weight_= (weight:Int) :Unit ={this._weight = weight }override def toString() :String ={/* 如果有返回值,最后一行代码,可以把return省略 *///"name:" + this.name + ";age:" + this.age ; /* s:占位符:$(占位符)后面直接跟上属性的名字 */s"name:$name;age:$age" }}/* 创建对象 */var p1 = new Person(20,"张三");println("toString:" + p1.toString());/* 创建对象 * 属性=值,单独的赋值,另外的一个,表示使用默认值* */var p2 = new Person(name="李四");println("toString:" + p2.toString());println("==p2.weight==" + p2.weight)/* 设置值 *///p2.weight_=(300);p2.weight = 300 ; println("==p2.weight==" + p2.weight)}/*** 元组*/def base_03 ={/* 创建一个元组 */var tuple2 = ("张三",20):Tuple2[String,Int];println("toString:" + tuple2); /* 取第二个值 */println("key:" + tuple2._1); println("value:" + tuple2._2); /* 就是一个类 */var tuple3 = new Tuple2("李四",20);println("key:" + tuple3._1); println("value:" + tuple3._2); /* 第三种写法 */var tuple4 = ("王五",30);println("key:" + tuple4._1); println("value:" + tuple4._2); /* 解构元组 */var (name,age) = tuple4 ; println("name" + name); println("age:" + age); /* 准备一个List* List里面放的可以是元组;tuple2*  */var list = List( ("张三",20),("李四",30), ("王五",40));/** 参数是一个函数;* f: Any => U* f: ((String, Int)) => U* */list.foreach( t => println(t._1 + "==循环==>" + t._2))/* 模式匹配 */ list.foreach( t => {/* 模式匹配特别像switch case* case后面跟的是条件;*  */t match {case ("张三",age) => println("张三,你老了,年龄:" + s"$age");case temp if(temp._1 == "李四") => {/* 如果访问的是元组;s后面的占位符要使用${变量名._2} */println(temp._1 + ",你更老了,年龄:" + s"${temp._2}");}case _ => println("===你更老===");}})/* List的另外一种循环* <-右边是集合,左边是临时的变量* * 把方法的名字叫数学符号;+,-,++*  */for( (name,age) <- list){println(name + "==循环==>" + age)}    /* ==========高阶函数==========* 方法的参数是函数;* 方法的返回值也可以是函数*  */var list2 = List(1,35,73,10)/* 第一种写法 */var doubleInt = (t:Int) => {var t2  = t * 2 ;println("第一种写法==循环==" + t2 )};list2.foreach(doubleInt)/* 第二种写法 */list2.foreach( t => {var t2  = t * 2 ;println("第二种写法==循环==" + t2 )} );/* 第三种写法* =>左半已经可以自动推断参数的类型,那就可直接省略掉* _不能和其它类型运算*  */list2.foreach( println(_) )/* 柯里化 */var result = list2.foldLeft(0)(_ + _);println("----result----" + result ) }
}

最通俗易懂的Scala初级知识相关推荐

  1. 23篇大数据系列(二)scala基础知识全集(史上最全,建议收藏)

    作者简介: 蓝桥签约作者.大数据&Python领域优质创作者.管理多个大数据技术群,帮助大学生就业和初级程序员解决工作难题. 我的使命与愿景:持续稳定输出,赋能中国技术社区蓬勃发展! 大数据系 ...

  2. 台式电脑如何截屏_如何选购台式电脑显卡?小白装机通俗易懂的独立显卡知识指南...

    对于游戏玩家和3D设计人员以及挖矿人员来说,显卡的选择无疑是重中之重,重要性可能甚至超过了核心硬件-CPU.我们在选购独立显卡的时候,通常小白只看显存大小,其实这是最大的选购误区,然而决定显卡的性能不 ...

  3. Scala初级实践——统计手机耗费流量(1)

    Scala初级实践--统计手机耗费流量(1) [实验描述] 本实验主要使用Scala语言来实现对手机流量的计算.在该实验中,共有四个需求: 1)统计每一个手机号耗费的总上行流量.下行流量.总流量 2) ...

  4. 04-如何选购台式电脑显卡?小白装机通俗易懂的独立显卡知识指南

    对于游戏玩家和3D设计人员以及挖矿人员来说,显卡的选择无疑是重中之重,重要性可能甚至超过了核心硬件-CPU.我们在选购独立显卡的时候,通常小白只看显存大小,其实这是最大的选购误区,然而决定显卡的性能不 ...

  5. 09-如何选购台式电脑电源?小白装机通俗易懂的电脑电源选购知识指南

    电源虽然不影响一台电脑的性能,但是它决定了电脑的稳定性,电源相当于人体的心脏,给电脑各个部件提供合适的稳定电压,选购电源的重要性至关重要,不过大多数用户往往会忽视电源的重要性.那么如何选购台式电脑电源 ...

  6. 台式计算机显示器,显示器基础知识:通俗易懂的台式电脑显示器知识

    对于DIY装机,我们选购显示器只看尺寸大小和外观,而显示器的参数都往往被忽视,其实选择显示器也是有讲究了,不只是看看大小和外观那么简单.下面装机之家分享一下显示器基础知识,使用通俗易懂的方式介绍台式电 ...

  7. Scala基础知识(个人总结)

    声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章               2. 由于是个人总结, 所以用最精简的话语来写文章           ...

  8. Scala基础知识笔记2

    1 类 1.1 定义一个简单的类 1.2 field的getter 和 setter方法 感觉成员变量定义成  var 属性名=属性值即可,  不需要定义成 val 或者 private就行, // ...

  9. 计算机科学与技术初级知识,计算机科学与技术专业课程有哪些

    计算机科学与技术专业课程有哪些2021-06-15 14:18:02文/李文源 数字电路.计算机系统结构.算法.程序设计语言.软件工程.并行分布计算.智能技术.计算机图形学与人机交互等知识领域的基本内 ...

最新文章

  1. 14、四大组件--Service
  2. c/c++ 获取文件夹或目录下的文件
  3. To-do-List
  4. 网络中pkt是什么意思_网络流行语Cp、磕么?是什么意思?
  5. 卸载MySQL以及重装卡到Start Services的解决办法(亲测有效,刚重装成功)
  6. 更轻松的获取APK文件安装时间
  7. mysql手机号段地区库_最新全国手机号段归属地数据库下载(mysql+xlsx+txt格式)46万条...
  8. CISSP国际注册信息系统安全专家
  9. 图像降噪有哪些方法?
  10. 如何修改网络连接的网络位置
  11. 二月(不积跬步无以至千里)
  12. 三十岁以后,我一定能阔起来!
  13. shopify 与国内第三方建站服务平台的比较(店匠、shopline、shopyy、ueeshop)
  14. INFOR WMS仓储管理系统里常用表说明
  15. Mob研究院 |2019互联网医疗行业洞察
  16. P1873 [COCI 2011/2012 #5] EKO / 砍树
  17. stm32的语音识别_基于STM32的嵌入式语音识别模块设计实现
  18. md5压缩函数用java实现,MD5压缩算法介绍
  19. Python爬虫实战之爬取网站全部图片(二)
  20. C# Pdf添加页码(iTextSharp)

热门文章

  1. 小学四年级计算机制作月历教案,小学信息技术教案制作月历
  2. 荧光素FITC标记多糖,FITC-polysaccharide
  3. uniapp取消网络请求
  4. halfstone 原理_half of --中的一半.当它所指代的是不可数名词时.代表单数.如果half of 后边所接的是可数名词的复数.那么它所代表的也是复数概念....
  5. Unity HDRP示例场景解析
  6. AS3及FLEX百条常识
  7. linux下安装7z命令及7z命令的使用
  8. 转 光线追踪的基本原理
  9. 多层PCB主要制作难点,PCB工程师了解一下很有必要!
  10. 试图将驱动程序添加到存储区_新版Wii U模拟器CEMU 1.15.1将发布 提供众多改进