scala学习之scala快速入门(代码片段)

顧棟 顧棟     2022-12-15     576

关键词:

Scala的“味道”

原文地址: https://docs.scala-lang.org/overviews/scala-book/prelude-taste-of-scala.html

在本书中,我们假设您以前使用过 Java 之类的语言,并准备好查看一系列 Scala 示例以了解该语言的外观。 尽管这不是 100% 必要的,但如果您已经下载并安装了 Scala,它也会有所帮助,这样您就可以在进行过程中测试示例。 您还可以使用 ScalaFiddle.io 在线测试这些示例。

Overview 概述

在我们进入示例之前,这里有一些关于 Scala 的重要信息:

  • 这是一种高级语言
  • 它是静态类型的
  • 它的语法简洁但仍然可读——我们称之为富有表现力
  • 它支持面向对象编程 (OOP) 范式
  • 它支持函数式编程 (FP) 范式
  • 它有一个复杂的类型推断系统
  • Scala 代码生成在 Java 虚拟机 (JVM) 上运行的 .class 文件
  • 在 Scala 中使用 Java 库很容易

Hello, world

从《C 编程语言》这本书开始,以“Hello, world”示例开始编程书籍一直是一种传统,不要让人失望,这是在 Scala 中编写该示例的一种方式:

object Hello extends App 
    println("Hello, world")

将该代码保存到名为 Hello.scala 的文件后,您可以使用scalac 编译它:

$ scalac Hello.scala

如果您是从 Java 来到 Scala,scalac 就像 javac,该命令会创建两个文件:

  • Hello$.class
  • Hello.class

这些与您使用 javac 创建的“.class”字节码文件相同,它们已准备好在 JVM 中运行。 使用 scala 命令运行 Hello 应用程序:

$ scala Hello

我们将在接下来的课程中分享更多“Hello, world”示例,因此我们暂时保留该介绍。

The Scala REPL

Scala REPL(“Read-Evaluate-Print-Loop”)是一个命令行解释器,您可以将其用作测试 Scala 代码的“操场”区域。 我们在这里很早就介绍了它,以便您可以将它与后面的代码示例一起使用。

要启动 REPL 会话,只需在您的操作系统命令行中输入 scala,您将看到如下内容:

$ scala
Welcome to Scala 2.13.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.

scala> _

因为 REPL 是一个命令行解释器,它只是坐在那里等待你输入一些东西。 在 REPL 中,您键入 Scala 表达式以查看它们是如何工作的:

scala> val x = 1
x: Int = 1

scala> val y = x + 1
y: Int = 2

如这些示例所示,在 REPL 中键入表达式后,它会在提示后的行中显示每个表达式的结果。

Two types of variables

Scala 有两种类型的变量:

  • val is an immutable variable — like final in Java — and should be preferred
  • var creates a mutable variable, and should only be used when there is a specific reason to use it
  • Examples:
val x = 1   //immutable
var y = 0   //mutable

Declaring variable types

在 Scala 中,您通常创建变量而不声明它们的类型:

val x = 1
val s = "a string"
val p = new Person("Regina")

当您这样做时,Scala 通常可以为您推断数据类型,如以下 REPL 示例所示:

scala> val x = 1
val x: Int = 1

scala> val s = "a string"
val s: String = a string

此功能称为类型推断,它是帮助保持代码简洁的好方法。 您还可以显式声明变量的类型,但这通常不是必需的:

如您所见,该代码看起来不必要地冗长。

Control structures

这是 Scala 控制结构的快速浏览。

if/else

Scala 的 if/else 控制结构与其他语言类似:

if (test1) 
    doA()
 else if (test2) 
    doB()
 else if (test3) 
    doC()
 else 
    doD()

然而,与Java和许多其他语言不同的是,if/else构造返回一个值,因此,除了其他功能外,你可以将它用作一个三元操作符:

val x = if (a < b) a else b

match expressions

Scala 有一个match表达式,它最基本的用法就像一个 Java switch 语句:

val result = i match 
    case 1 => "one"
    case 2 => "two"
    case _ => "not 1 or 2"

匹配表达式不仅限于整数,它可以用于任何数据类型,包括布尔值:

val booleanAsString = bool match 
    case true => "true"
    case false => "false"

下面是一个 match 被用作方法体的例子,并且匹配许多不同的类型:

def getClassAsString(x: Any):String = x match 
    case s: String => s + " is a String"
    case i: Int => "Int"
    case f: Float => "Float"
    case l: List[_] => "List"
    case p: Person => "Person"
    case _ => "Unknown"

强大的匹配表达式是 Scala 的一大特色,我们将在本书后面分享更多示例。

try/catch

Scala 的 try/catch 控制结构可让您捕获异常。 它类似于Java,但其语法与匹配表达式一致:

try 
    writeToFile(text)
 catch 
    case fnfe: FileNotFoundException => println(fnfe)
    case ioe: IOException => println(ioe)

for loops and expressions

Scala for 循环——我们在本书中通常将其写为 for 循环——看起来像这样:

for (arg <- args) println(arg)

// "x to y" syntax
for (i <- 0 to 5) println(i)

// "x to y by" syntax
for (i <- 0 to 10 by 2) println(i)

您还可以将 yield关键字添加到 for 循环以创建产生结果的 for 表达式。 这是一个 for 表达式,它将序列 1 到 5 中的每个值加倍:

val x = for (i <- 1 to 5) yield i * 2

这是另一个遍历字符串列表的 for 表达式:

val fruits = List("apple", "banana", "lime", "orange")

val fruitLengths = for 
    f <- fruits
    if f.length > 4
 yield f.length

因为 Scala 代码通常是有意义的,我们可以想象你可以猜出这段代码是如何工作的,即使你之前从未见过 for 表达式或 Scala 列表。

while and do/while

Scala 也有 whiledo/while 循环。 这是它们的一般语法:

// while loop
while(condition) 
    statement(a)
    statement(b)


// do-while
do 
   statement(a)
   statement(b)
 
while(condition)

Classes

这里是一个Scala 类的例子:

class Person(var firstName: String, var lastName: String) 
    def printFullName() = println(s"$firstName $lastName")

这是您使用该类的方式

val p = new Person("Julia", "Kern")
println(p.firstName)
p.lastName = "Manes"
p.printFullName()

请注意,无需创建“get”和“set”方法来访问类中的字段。

作为一个更复杂的例子,这里有一个 Pizza 类,你将在本书后面看到:

class Pizza (
    var crustSize: CrustSize,
    var crustType: CrustType,
    val toppings: ArrayBuffer[Topping]
) 
    def addTopping(t: Topping): Unit = toppings += t
    def removeTopping(t: Topping): Unit = toppings -= t
    def removeAllToppings(): Unit = toppings.clear()

在该代码中,ArrayBuffer 就像 Java 的 ArrayListCrustSizeCrustTypeTopping 类未显示,但您可能无需查看这些类就可以理解该代码的工作原理。

Scala methods

就像其他 OOP 语言一样,Scala 类也有方法,这就是 Scala 方法语法的样子:

def sum(a: Int, b: Int): Int = a + b
def concatenate(s1: String, s2: String): String = s1 + s2

您不必声明方法的返回类型,因此如果您愿意,可以像这样编写这两个方法是完全合法的:

def sum(a: Int, b: Int) = a + b
def concatenate(s1: String, s2: String) = s1 + s2

这就是您调用这些方法的方式:

val x = sum(1, 2)
val y = concatenate("foo", "bar")

你可以用方法做更多的事情,比如为方法参数提供默认值,但现在这是一个好的开始。

Traits

Scala 中的特性非常有趣,它们还可以让您将代码分解为小的模块化单元。 为了演示特征,这里有一个本书后面的例子。 鉴于这三个特点:

trait Speaker 
    def speak(): String  // has no body, so it’s abstract


trait TailWagger 
    def startTail(): Unit = println("tail is wagging")
    def stopTail(): Unit = println("tail is stopped")


trait Runner 
    def startRunning(): Unit = println("I’m running")
    def stopRunning(): Unit = println("Stopped running")

您可以创建一个 Dog 类来扩展所有这些特征,同时为 speak 方法提供行为:

class Dog(name: String) extends Speaker with TailWagger with Runner 
    def speak(): String = "Woof!"

类似地,这是一个 Cat 类,它展示了如何覆盖多个 trait 方法:

class Cat extends Speaker with TailWagger with Runner 
    def speak(): String = "Meow"
    override def startRunning(): Unit = println("Yeah ... I don’t run")
    override def stopRunning(): Unit = println("No need to stop")

如果代码是有意义的——太好了,你对trait很满意!如果没有,不要担心,我们会在后面的书中详细解释。

Collections classes

如果您是从Java学习Scala的,并且已经准备好真正投入学习Scala,那么在Scala中使用Java集合类是可能的,有些人在熟悉Scala的同时也会这样做几个星期或几个月。但是强烈建议您尽快学习基本的Scala集合类——ListListBufferVectorArrayBufferMapSet。Scala集合类的一个巨大好处是,它们提供了许多功能强大的方法,您希望尽快开始使用这些方法来简化代码。

Populating lists

有时创建填充数据的示例列表会很有帮助,Scala 提供了许多填充列表的方法。 这里仅仅是少数:

val nums = List.range(0, 10)
val nums = (1 to 10 by 2).toList
val letters = ('a' to 'f').toList
val letters = ('a' to 'f' by 2).toList

Sequence methods

虽然您可以使用许多顺序集合类 — ArrayArrayBufferVectorList等 — 让我们看一些您可以使用 List 类做什么的示例。 鉴于这两个列表

val nums = (1 to 10).toList
val names = List("joel", "ed", "chris", "maurice")

这是一个 foreach 方法:

scala> names.foreach(println)
joel
ed
chris
maurice

这是一个filter 然后是一个foreach方法

scala> nums.filter(_ < 4).foreach(println)
1
2
3

这里有一些关于Map方法的例子

scala> val doubles = nums.map(_ * 2)
doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

scala> val capNames = names.map(_.capitalize)
capNames: List[String] = List(Joel, Ed, Chris, Maurice)

scala> val lessThanFive = nums.map(_ < 5)
lessThanFive: List[Boolean] = List(true, true, true, true, false, false, false, false, false, false)

即使没有任何解释,您也可以看到 map 是如何工作的:它将您提供的算法应用于集合中的每个元素,为每个元素返回一个新的、转换后的值。

如果您准备好了解最强大的集合方法之一,请使用 foldLeft:

scala> nums.foldLeft(0)(_ + _)
res0: Int = 55

scala> nums.foldLeft(1)(_ * _)
res1: Int = 3628800

一旦您知道 foldLeft 的第一个参数是seed value,您就可以猜测第一个示例得出nums中数字的总和,而第二个示例返回所有这些数字的乘积。

Scala 集合类有很多(很多!)更多方法可用,其中许多方法将在接下来的集合课程中演示,但希望这能让您了解它们的功能。

Tuples

元组让您可以将不同的元素集合放在一个小容器中。 一个元组可以包含 2 到 22 个值,并且所有值都可以有不同的类型。 例如,这是一个包含三种不同类型(IntDoubleString)的元组:

(11, 11.0, "Eleven")

这被称为 Tuple3,因为它包含三个元素。

元组在很多地方都很方便,例如您可能会在其他语言中使用临时类。 例如,您可以从方法返回一个元组而不是返回一个类:

def getAaplInfo(): (String, BigDecimal, Long) = 
    // get the stock symbol, price, and volume
    ("AAPL", BigDecimal(123.45), 101202303L)

然后你可以将方法的结果分配给一个变量:

val t = getAaplInfo()

一旦你有了一个元组变量,你就可以通过数字访问它的值,前面是下划线:

t._1
t._2
t._3

REPL 演示了访问这些字段的结果:

scala> t._1
res0: String = AAPL

scala> t._2
res1: scala.math.BigDecimal = 123.45

scala> t._3
res2: Long = 101202303

元组的值也可以使用模式匹配来提取。 在下一个示例中,元组内的字段被分配给变量symbolpricevolume

val (symbol, price, volume) = getAaplInfo()

REPL 再次演示了结果:

scala> val (symbol, price, volume) = getAaplInfo()
symbol: String = AAPL
price: scala.math.BigDecimal = 123.45
volume: Long = 101202303

当你想快速(和临时)将一些东西组合在一起的时候,元组是很好的。 如果您注意到多次使用相同的元组,那么声明一个专用的 case 类可能会很有用,例如:

case class StockInfo(symbol: String, price: BigDecimal, volume: Long)

What we haven’t shown

虽然这是 Scala 的旋风式介绍,大约有十页印刷,但还有很多东西我们还没有展示,包括:

  • 字符串和内置数字类型
  • 包装和进口
  • 如何在 Scala 中使用 Java 集合类
  • 如何在 Scala 中使用 Java 库
  • 如何构建 Scala 项目
  • 如何在 Scala 中执行单元测试
  • 如何编写 Scala shell 脚本
  • Maps、Sets 和其他集合类
  • 面向对象编程
  • 函数式编程
  • 与并发特性
  • 更多的 …
    如果您喜欢到目前为止所看到的内容,我们希望您会喜欢本书的其余部分。

scala学习之scala中的类(代码片段)

文章目录SCALACLASSESBasicclassconstructor`val`makesfieldsread-onlyClassconstructorsOtherScalaclassexamplesAUXILIARYCLASSCONSTRUCTORSNotesSUPPLYINGDEFAULTVALUESFORCONSTRUCTORPARAMETERSBenefitsBonus 查看详情

scala学习之traits和抽象类(代码片段)

文章目录SCALATRAITSANDABSTRACTCLASSESUsingScalaTraitsasInterfacesAsimpleexampleExtendingatraitExtendingmultipletraitsUSINGSCALATRAITSLIKEABSTRACTCLASSESAfirstexampleOverridinganimplementedmethodMixinginmu 查看详情

scala学习之函数式风格编程(代码片段)

FUNCTIONALPROGRAMMINGhttps://docs.scala-lang.org/overviews/scala-book/functional-programming.htmlScala允许您以面向对象编程(OOP)风格、函数式编程(FP)风格甚至混合风格编写代码,结合使用这两种方法。本书假设您是从Java、C++或C#等OOP语言来... 查看详情

scala学习之tuples和oop示例(代码片段)

文章目录AFEWMISCELLANEOUSITEMSTUPLESAfewmoretupledetailsReturningatuplefromamethodTuplesaren’tcollectionsANOOPEXAMPLEAfewclassesAddingbehaviortoPizzaAddingbehaviortoOrderTestingthoseclassesExperimentwitht 查看详情

scala深入学习之函数学习(代码片段)

目录一、函数的定义二、匿名函数三、递归函数四、无参函数五、方法和函数的区别联系一、函数的定义代码示例:packagefunctionDemo/***@author:蔡政洁*@email:caizhengjie888@icloud.com*@date:2020/8/23*@time:2:14下午*/objectFunction... 查看详情

scala学习之「trait」(代码片段)

trait调用链Scala中支持让类继承多个trait后,依次调用多个trait中的同一个方法,只要让多个trait的同一个方法中,在最后都执行super.方法即可类中调用多个trait中都有的这个方法时,首先会从最右边的trait的方法开始执行,然后依... 查看详情

scala基础语法之trait详解(代码片段)

...ala系列学习笔记:Scala概述与开发环境配置Scala基础学习之运算符Scala基础学习之for循环和while循环一文掌握scala中的方法和函数Scala基础:类和对象、访问修饰符和构造器Scala的继承和抽象类本章节目标能够使用trait独立完... 查看详情

scala的继承和抽象类(代码片段)

...ala系列学习笔记:Scala概述与开发环境配置Scala基础学习之运算符Scala基础学习之for循环和while循环一文掌握scala中的方法和函数Scala基础:类和对象、访问修饰符和构造器本章节目标掌握继承和抽象类相关知识点掌握匿名... 查看详情

大数据学习之scala语言基本语法学习36

一:scala简介官网:https://www.scala-lang.org/Scala语言很强大,集成了面向对象和函数式编程的特点。运行在JVM(jdk)。大数据中为什么学习scala?spark是scala语言编写。python写spark挺好的java写spark很糟糕(代码实在是太多了)scala写spark很... 查看详情

scala学习之「类——基本概念2」(代码片段)

目录内部类extendsoverride和superoverridefieldisInstanceOf和asInstanceOfgetClass和classOf内部类importscala.collection.mutable.ArrayBufferclassClassclassStudent(valname:String)//此处为内部类valstudents=newArrayBuffer[Student]defgetStudent(name:String)=newStudent(name)valc1=newClassval... 查看详情

scala学习之:flattenanestedliststructure

题目要求:(**)Flattenanestedliststructure.Example:scala>flatten(List(List(1,1),2,List(3,List(5,8))))res0:List[Any]=List(1,1,2,3,5,8)参考:http://blog.thedigitalcatonline.com/blog/2015/04/07/99-scala-proble 查看详情

scala基础学习之for循环和while循环(代码片段)

章节目标掌握分支结构的格式和用法掌握for循环和while循环的格式和用法掌握控制跳转语句的用法掌握循环案例理解do.while循环的格式和用法1.流程控制结构1.1概述在实际开发中,我们要编写成千上万行代码,代码的顺序不同,执行结... 查看详情

scala学习之爬豆瓣电影

简单使用Scala和Jsoup对豆瓣电影进行爬虫,技术比較简单易学。写文章不易,欢迎大家採我的文章,以及给出实用的评论,当然大家也能够关注一下我的github;多谢。1、爬虫前期准备找好须要抓取的链接:https://movie.douban.com/tag/%E... 查看详情

spark学习之scala编程

 一、Scala语言基础1、Scala语言简介Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。学习Scala编程语言,为后续学习Spark... 查看详情

scala学习之:listspan用法

Packconsecutiveduplicatesoflistelementsintosublists.Ifalistcontainsrepeatedelementstheyshouldbeplacedinseparatesublists.Example:scala>pack(List(‘a,‘a,‘a,‘a,‘b,‘c,‘c,‘a,‘a,‘d,‘e,‘e,‘e,‘e))res0:List[ 查看详情

scala学习之:list.fill用法

题目描述:Decodearun-lengthencodedlist.Givenarun-lengthcodelistgeneratedasspecifiedinproblemP10,constructitsuncompressedversion.Example:scala>decode(List((4,‘a),(1,‘b),(2,‘c),(2,‘a),(1,‘d),(4,‘e)))res0: 查看详情

scala基础学习之运算符(代码片段)

章节目标理解运算符的相关概述掌握算术,赋值,关系,逻辑运算符的用法掌握交换变量案例理解位运算符的用法1.算术运算符1.1运算符简介用来拼接变量或者常量的符号就叫:运算符,而通过运算符连接起来的式子就叫:表达式.实际开... 查看详情

scala学习之面向对象

==> 类        ---> 类的定义class Student{    // 定义属性    private var stuName:String = 查看详情