scala repl_Scala教程– Scala REPL,表达式,变量,基本类型,简单函数,保存和运行程序,注释...

scala repl

前言

该是第几个斯卡拉教程我创建了我的2011年秋季毕业的介绍计算语言学课程 ,在德克萨斯大学奥斯汀分校,松散的基础上类似的教程, 卡特琳的Erk用于创建类似的课程教学的Python 。 这些教程假定没有以前的编程背景,但是不幸的是,这种假设在help-folks-learn-Scala领域中仍然很少见,并且或多或少需要创建这些教程。 我知道的一个例外是SimplyScala

注意 :如果您已经知道一种编程语言,那么本教程可能对您不是很有用。 (尽管稍后可能会进行一些我希望进行的函数式编程,所以请回来查看。)与此同时,请查看我在课程链接页面中列出的现有Scala学习资料

本教程假定您已经安装了Scala,并且正在使用某种形式的Unix(如果使用Windows,则需要研究Cygwin)。 如果您对此有疑问,可以通过在SimplyScala的代码框中评估示例来尝试这些示例。

Scala表达式,变量和基本类型的(部分)入门

我们将使用Scala REPL输入Scala表达式,并查看评估它们的结果。 REPL代表read-eval(uate)-print-loop,它是一个程序,该程序(1)读取您键入的表达式,(2)使用Scala编译器对其求值,(3)打印出结果。评估,然后(4)等待您输入其他表达式。

注意 :在REPL中实际键入下面给出的命令非常重要。 如果您只是阅读了一下,在很多情况下,它将看起来很明显(是),但是,刚接触编程的人通常会通过实际尝试来找到很多理解上的空白。 特别是,编程语言非常精确,因此它们会按照您告诉他们的方式去做-几乎可以肯定会弄乱一些东西,并从中学到东西。

在Unix shell中,键入:

$ scala

您应该看到类似以下的内容:

Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.
 
scala>

scala>行是REPL等待您输入表达式的提示。 让我们输入一些。

scala> "Hello world"
res0: java.lang.String = Hello world
 
scala> 2
res1: Int = 2

REPL告诉我们,第一个是一个包含字符Hello worldString ,第二个是一个Int,其值是整数2 。 字符串和整数是类型 -这是一个简单但重要的区别,有时需要新手程序员花点时间才能习惯。 这样,Scala便可以知道要使用数值 2(Int)或代表2(字符串)的字符时该怎么做。 例如,这里是后者。

scala> "2"
res3: java.lang.String = 2

Scala知道不同类型提供不同的动作。 例如,可以将Ints相互添加。

scala> 2+3
res4: Int = 5

Scala评估结果并将结果打印到屏幕上。 毫不奇怪,结果就是您认为的样子。 对于字符串,加法没有意义,但+运算符表示字符串的串联。

scala> "Portis" + "head"
res5: java.lang.String = Portishead

因此,如果您考虑字符串“ 2? 和字符串“ 3”,并在其上使用+运算符,您不会得到“ 5? -相反,您得到“ 23?”。

scala> "2" + "3"
res6: java.lang.String = 23

我们可以要求Scala使用print命令显示对给定表达式求值的结果。

scala> print ("Hello world")
Hello world
scala> print (2)
2
scala> print (2 + 3)
5

请注意,结果是打印操作,而不是带有类型的值。 对于最后一项,发生的是:

  1. Scala计算2 + 3,即5。
  2. Scala将该值传递给命令print
  3. 打印输出“ 5?

您可以将print命令视为动词,并将其参数(例如Hello world2 )视为其对象。

我们经常需要将对表达式求值的结果存储到变量中,以备后用(实际上,如果不这样做,编程是无法完成的)。 让我们先简单地做一下,将上面的print语句分解为两个步骤。

scala> val x = 2 + 3
x: Int = 5
 
scala> print (x)
5

在这里, x是一个变量,我们通过在其前面加上val来表明它是一个固定变量,其值不能更改。

您可以选择变量的名称,但是它们必须遵循一些规则。

  • 变量名称可以包含:字母,数字,下划线
  • 他们不能以数字开头
  • 它们不得与Scala已定义的“保留字”之一相同,例如forifdefvalvar。

变量的典型名称将是字符串,例如xy1resultfirstNamehere_is_a_long_variable_name

返回变量x ,我们现在可以将其用于其他计算。

scala> x + 3
res12: Int = 8
 
scala> x * x
res13: Int = 25

当然,我们可以将这种计算的结果分配给其他变量。

scala> val y = 3 * x + 2
y: Int = 17

注意,Scala知道在这种计算中乘法优先于加法。 如果要覆盖它,则需要使用括号来表示它,就像在基本代数中一样。

scala> val z = 3 * (x + 2)
z: Int = 21

现在,让我们介绍另一种Double类型,用于处理实数值。 到目前为止考虑的整数是整数,可以很好地与乘法相乘,但是与除法一起使用时,可能会导致您可能无法预期的行为。

scala> 5 * 2
res12: Int = 10
 
scala> 7/2
res13: Int = 3

您可能期望后者获得3.5。 但是,由于7和2均为Ints,Scala返回一个Int —特别是它返回分母可以完全进入分子的次数。 为了获得您通常在这里想要的结果,您需要使用Doubles,例如以下代码。

scala> 7.0/2.0
res14: Double = 3.5

现在,结果就是您期望的值,并且它是Double类型的。 Scala使用约定来了解值的类型,例如,它知道引号中的内容是字符串,即带有“。”的数字。 在他们是双打,而数字没有“。” 是整数。 这是Scala 推断变量类型的重要部分,这在同类语言(称为静态类型语言)中是非常有用且有些独特的属性。 要更详细地了解这一点,请注意,您可以明确地告诉Scala变量的类型是什么。

scala> val a: Int  = 2
a: Int = 2

该行的a:Int部分表示变量a具有Int类型。 以下是一些其他类型不同的变量的示例。

scala> val b: Double = 3.14
b: Double = 3.14
 
scala> val c: String = "Hello world"
c: String = Hello world

因为Scala已经知道这些类型,所以在这些情况下指定它们是多余的。 但是,当表达式更复杂时,有时有必要明确指定类型。

重要的是,我们不能为变量分配与表达式结果冲突的类型。 在这里,我们尝试将Double值分配给Int类型的变量,Scala报告错误。

scala> val d: Int = 6.28
<console>:7: error: type mismatch;
found   : Double(6.28)
required: Int
val d: Int = 6.28
^

在许多情况下,尤其是开始编程时,您不必担心声明变量的类型。 我们将看到在进行过程中有必要的情况。

除了使用val声明的变量外,Scala还允许使用var声明变量-这些变量可以重新分配其值。 一些示例是了解差异的最简单方法。

scala> val a = 1
a: Int = 1
 
scala> a = 2
<console>:8: error: reassignment to val
a = 2
^
 
scala> var b = 5
b: Int = 5
 
scala> b = 6
b: Int = 6

您可以将val变量视为一个密封的玻璃容器,可以在其中查看其值,但是不能在其中放入任何新东西,而将var变量视为一个可打开的容器,它既可以查看值也可以交换旧值的新价值。 我们将主要集中在使用val上,因为它们最终在与函数式编程结合时会提供许多优势,并且因为我希望让您在起步时就以val而不是var的方式进行思考。

功能

当在函数的上下文中使用变量时,变量更为有用,在这种情况下,函数的用户可以将x等变量注入不同的值。 让我们考虑将华氏度转换为摄氏度。 要将华氏温度87、92和100转换为摄氏温度,我们可以执行以下操作。

scala> (87 - 32) * 5 / 9.0
res15: Double = 30.555555555555557
 
scala> (92 - 32) * 5 / 9.0
res16: Double = 33.333333333333336
 
scala> (100 - 32) * 5 / 9.0
res17: Double = 37.77777777777778

显然,这里有很多重复。 函数使我们可以指定这种计算的共同部分,而变量则可以指定可能不同的部分。 在转换情况下,唯一改变的是华氏温度读数。 这是我们在Scala中声明适当函数的方式。

scala> def f2c (x: Double) = (x - 32) * 5/9.0
f2c: (x: Double)Double

分解为以下内容:

  • def是Scala关键字,指示正在定义函数
  • f2c是函数的名称
  • (x:Double)是函数的参数,它是名为Double的x类型的变量
  • (x – 32)* 5 / 9.0是函数的主体,它将采用函数用户给出的值,从中减去32,然后将结果乘以五分之九

使用函数很容易-给出函数的名称,然后在括号中提供要传递给函数的值。

scala> f2c(87)
res18: Double = 30.555555555555557
 
scala> f2c(92)
res19: Double = 33.333333333333336
 
scala> f2c(100)
res20: Double = 37.77777777777778

等等。 对于每次调用,函数都会对x的表达式求值,该表达式等于传递给函数的值。 现在,我们不必一次又一次地重新键入所有常见内容。

函数可以具有多个参数。 例如,以下是一个函数,该函数接受两个整数,将每个整数平方,然后将平方值相加。

scala> def squareThenAdd (x: Int, y: Int) = x*x + y*y
squareThenAdd: (x: Int, y: Int)Int
 
scala> squareThenAdd(3,4)
res21: Int = 25

确实与显式执行相同。

scala> 3*3 + 4*4
res22: Int = 25

函数的一个重要方面是必须绑定所有变量。 如果没有,我们会报错。

scala> def badFunctionWithUnboundVariable (x: Int) = x + y
<console>:8: error: not found: value y
def badFunctionWithUnboundVariable (x: Int) = x + y

函数可以完成比我在此展示的更加复杂和有趣的事情,我们将在另一篇教程中了解。

在文本编辑器中编辑程序并在命令行上运行它们

REPL对于试用Scala表达式并查看如何实时评估它们非常有用,但是实际的程序开发是通过编写文本文件来完成的,该文本文件包含一系列执行有趣行为的表达式。 这样做很简单。 打开一个文本编辑器(有关一些建议,请参见课程链接页面 ),并将以下内容作为第一行,没有其他内容。

print ("Hello world")

将此文件另存为HelloWorld.scala ,确保将其另存为文本。 然后在Unix shell中,转到保存该文件的目录,然后键入以下内容。

$ scala HelloWorld.scala

您会看到输出了Hello world ,但是紧随其后的是Unix提示符。 您可能希望它能打印出来,然后在下一行保留Unix提示符; 但是,在print命令或我们要求它打印的字符串中没有任何内容指示应该使用换行符。 要解决此问题,请返回编辑器,并将行更改为以下内容。

print ("Hello world\n")

运行此命令时,Unix提示符将出现在Hello world后面的行中。 像\ n这样的字符是元字符,表示标准输出(例如字母,数字和符号)以外的输出。

现在,您还可以通过编写获得相同的结果。

println ("Hello world")

函数printprintln相同,除了后者总是在输出末尾添加换行符-这是经常需要的,从而简化了程序员的工作。 但是,在输出字符串时,我们仍然经常需要使用换行符和其他字符。 例如,将以下内容放入HelloWorld.scala并再次运行。

println("Hello world\nHere is a list:\n\t1\n\t2\n\t3")

从输出中,应该很清楚' \ t '的含义。 注意,由于使用了println而不是print ,所以不必在最后3个字符后加上' \ n '。

这是一个琐碎的程序,但是总的来说,它们往往变得相当复杂。 这是代码注释派上用场的地方。 您可以使用两个正斜杠来指示Scala应该忽略一行作为注释。 注释可用于指示程序的作者,许可证的用途,帮助他人(以及您将来的自己)的文档,以了解代码各部分的功能,并注释掉您所编写的代码行不想删除,但您希望暂时不活动。

这是一个稍微冗长的程序,其中包含注释和功能定义以及这些功能以及打印的使用。

// Author: Jason Baldridge (jasonbaldridge@gmail.com)
 
// This is a trivial program for students learning to program with Scala.
 
// This is a comment. The next line defines a function that squares
// its argument.
def sq (x: Int) = x * x
 
// The next line prints the result of calling sq with the argument 3.
println("3 squared = " + sq(3))
 
// The next line is commented out, so even though it is a valid Scala
// expression, it won't be evaluated by Scala.
// println("4 squared = " + sq(4))
 
// Now, we define a function that uses the previously defined sq
// (rather than using x*x and y*y as before).
def squareThenAdd (x: Int, y: Int) = sq(x) + sq(y)
 
// Now we use it.
println("Squaring 3 and 4 and adding the results = "
        + squareThenAdd(3,4))

将其另存为ScalaFirstStepsPart1.scala并使用Scala可执行文件运行。 您应该看到以下结果。

$ scala ScalaFirstStepsPart1.scala
3 squared = 9
Squaring 3 and 4 and adding the results = 25

看起来不错吧? 但是这些打印语句是怎么回事? 前面我们看到2 + 3等于5,但是“ 2?+” 3? 计算结果为“ 23”,这里我们在字符串和整数上使用+。 那不应该导致错误吗? Scala正在为我们自动将Int转换为字符串,这大大简化了结果的输出。 这意味着我们可以做以下事情(回到使用REPL)。

scala> println("August " + 22 + ", " + 2011)
August 22, 2011

这似乎毫无意义,因为我们可能刚刚写过“ 2011年8月22日?”,但是在此示例中它会更有用:我们可以通过为今天使用Int并在其中添加一个Int来命名明天。

scala> val dayOfTheMonthToday = 22
dayOfTheMonthToday: Int = 22
 
scala> println("Today is August " + dayOfTheMonthToday + " and tomorrow is August " + (dayOfTheMonthToday+1))
Today is August 22 and tomorrow is August 23

请注意, (dayOfTheMonthToday + 1)部分实际上是Int加法,并且其结果将转换为与该字符串的其余部分串联的字符串。 这个示例仍然相当人为设计(显然并不能解决月底的所有问题),但是当您开始使用更复杂的程序时,这种自动转换会被大量使用。 而且,也许甚至更明显地,我们可能合理地希望添加一个Int和Double。

scala> 2 + 3.0
res27: Double = 5.0

在这里,结果是Double,因为它是比Int更通用的类型。 这种自动转换经常发生,而且您通常甚至不会意识到这种情况正在发生。

要注意的另一件事是,最后一个打印语句遍历了多行。 我们将看到有关多行语句的规则的更多信息,但此示例可能显示了最容易记住的规则:当您使用“(”打开括号时,您可以继续多行直到其伙伴遇到“)”。 因此,例如,我们可以完成以下非常分散的声明。

println(
  "Squaring 3 and 4 and adding the results = "
 
  +
 
  squareThenAdd(3,4)
)

如上所述,除了用于在作为函数参数的一堆代码中进行装箱外,括号对于指示组合多个项目的优先顺序也非常有用,例如指示在乘法之前应进行加法运算,或者应该在String串联之前完成Int加法,如本教程前面所示。 基本上,括号通常是可选的,但是如果您不记得将表达式分组在一起的默认规则是什么,则可以使用括号将它们显式分组。

参考: 面向 初学者的 Scala的第一步,来自BCG博客的JCG合作伙伴 Jason Baldridge的 第1部分

相关文章 :


翻译自: https://www.javacodegeeks.com/2011/09/scala-tutorial-scala-repl-expressions.html

scala repl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值