zoukankan      html  css  js  c++  java
  • Scala学习(一)--Scala基础学习

    Scala基础学习

    摘要

    在篇主要内容:如何把Scala当做工业级的便携计算器使用,如何用Scala处理数字以及其他算术操作。在这个过程中,我们将介绍一系列重要的Scala概念和惯用法。同时你还将学到作为初学者如何浏览Scaladoc文档

    1. 使用Scala解释器

    2. 用var和val定义变量

    3. 数值类型

    4. 使用操作符和函数

    5. 浏览Scaladoc

    Scala解释器

    启动Scala解释器的步骤如下:

    安装Scala

    确保scala/bin目录位于系统PATH中

    在你的操作系统中打开命令行窗口,键入scala并按Enter键

    现在键人命令,然后按Enter键。每一次,解释器都会显示出结果。例如,当你键人"8*5+2"(如下面加粗的文字),将得到42:

    答案被命名为res0,你可以在后续操作中使用这个名称:

    正如你所看到的,解释器同时还会显示结果的类型,拿本例来说就是Int、Double和java.lang.String

    还可以调用方法,根据启动解释器的方式的不同,你可能可以使用Tab键补全而不用完整地手工键人方法名。你可以试着键人res2.to,然后按Tab键,如果解释器给出了如下选项:

    说明Tab键补全功能是好的。接下来键入U并再次按Tab键,你应该就能定位到单条补全如下:

    同样地,可以试试按T和J方向键。在大多数实现当中,你将看到之前提交过的命令,并且可以进行编辑。用方向键和Del键将上一条命令修改为:

    正如你所看到的,Scala解释器读到一个表达式,对它进行求值,将它打印出来,接着再继续读下一个表达式。这个过程被称做读取求值打印循环,即REPL。从技术上讲,scala程序并不是一个解释器。实际发生的是,你输入的内容被快速地编译成字节码,然后这段字节码交由Java虚拟机执行。正因如此,大多数Scala程序员更倾向于将它称做"REPL"。

    声明值和变量

    声明值

    除了直接使用res0、res1等这些名称之外,你也可以用val定义自己的名称:

    以val定义的值实际上是一个常量,你无法改变它的内容:

    声明变量

    如果要声明其值可变的变量,可以用var定义其值可变的变量

    需要注意的是,不需要给出或者变量的类型这个信息可以从你用来初始化它的表达式推断出来。但还需注意一点,声明值或变量但不做初始化会报错。不过,在必要的时候,你也可以指定类型。例如:

    由上图运行的结果可知,在Scala中,变量或函数的类型总是写在变量或函数名称的后面。这使得我们更容易阅读那些复杂类型的声明。同时还需注意的是,在变量声明或赋值语句之后,我们并没有使用分号。在Scala中,仅当同一行代码中存在多条语句时才需要用分号隔开

    常用类型

    基本数据类型:

    到目前为止你已经看到过Scala数据类型中的一些,比如Int和Double,和Java样Scala也有7种数值类型:Byte、Char、Short、Int、Long、Float和Double,以及1个Boolean类型。跟Java不同的是,这些类型是类。Scala并不刻意区分基本类型引用类型。你可以对数字执行方法,例如:

    scala> 1.toString

    res6: String = 1

    或者,更有意思的是,你可以:

    scala> 1.to(10)

    res7: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8,9, 10)

    在Scala中,我们不需要包装类型。在基本类型包装类型之间的转换是Scala编译器的工作。举例来说,如果你创建一个Int的数组,最终在虚拟机中得到的是一个int[]数组。

    基本数据类型转换:

    正如你在前面看到的那样,Scala用底层的java.lang.String类来表示字符串。不过,它通过StringOps类给字符串追加了上百种操作。举例来说,intersect方法输出两个字符串共通的一组字符:

    scala> "Hello".intersect("World")

    res8: String = lo

    在这个表达式中java.lang.String对象"Hello"被隐式地转换成了一个StringOps对象,接着StringOps类的intersect方法被应用。因此,在使用Scala文档的时候,记得要看一下StringOps类。同样地,Scala还提供了RichlntRichDoubleRichChar等。它们分别提供了它们可怜的堂兄弟们IntDoubleChar等,所不具备的便捷方法。我们前面用到的to方法事实上就是Richlnt类中的方法。在表达式:1.to (10)中,Int值1首先被转换成Richlnt然后再应用to方法。

    最后,还有BiglntBigDecimal类,用于任意大小(但有穷)的数字。这些类背后分别对应的是java.math.Biglnteger和java.math.BigDecimal

    注意:在Scala中,我们用方法,而不是强制类型转换,来做数值类型之间的转换。举例来说,99.44.tolnt得到99,99.toChar得到'c'。当然和Java一样,toString任意的对象转换成字符串。要将包含了数字的字符串转换成数值,使用tolnt或toDouble。例如,"99.44".toDouble得到99.44。

    算术和操作符重载

    Scala的算术操作符和你在Java或C++中预期的效果是一样的:

    val answer=8*5+2

    算术操作符:+ -*/%等操作符完成的是它们通常的工作,位操作符:&|^ >><<也一样。只有一点特别的,这些操作符实际上是方法。例如:

    a+b

    是如下方法调用的简写:

    a.+(b)

    这里的+方法名。通常来说,你可以用:

    a方法b

    作为以下代码的简写:

    a.方法(b)

    这里的方法是一个带有两个参数的方法(一个隐式的和一个显式的)。例如

    1.to (10)

    可以写成:

    1 to10

    调用函数方法

    除了方法之外,Scala还提供函数。相比Java,在Scala中使用数学函数更为简单,你不需要从某个类调用它的静态方法

    scala> import scala.math._

    import scala.math._

    scala> sqrt(2)

    res15: Double = 1.4142135623730951

    scala> pow(2,4)

    res16: Double = 16.0

    scala> min(3,Pi)

    res18: Double = 3.0

    这些数学函数是在scala.math包中定义的。你可以用如下语句进行引入:

    import scala.math._//在Scala中,_字符是"通配符",类似Java中的*字符

    Scala没有静态方法,不过它有个类似的特性,叫做单例对象singleton object。通常,一个类对应有一个伴生对象companion object,其方法就跟Java中的静态方法一样

    apply方法

    在Scala中,我们通常都会使用类似函数调用的语法。举例来说,如果S是一个字符串,那么S(i)就是该字符串的第i个字符。在C++中,你会写:S[i];而在Java中,你会这样写:S.charAt(i)。在REPL中运行如下代码:

    scala> "Hello"(4)

    res19: Char = o

    scala> "Hello"(0)

    res20: Char = H

    scala>

    你可以把这种用法当做是()操作符重载形式,它背后的实现原理是一个名为apply的方法。举例来说,在StringOps类的文档中,你会发现这样一个方法:

    def apply(n: Int): Char

    也就是说,"Hello"(4)是如下语句的简写:

    "Hello".apply(4)

    如果你去看Biglnt伴生对象的文档,就会看到让你将字符串数字转换为Biglnt对象的apply方法。举例来说,如下调用

    Biglnt ("1234567890")

    是如下语句的简写:

    Biglnt.apply("1234567890")

    这个语句产出一个新的Biglnt对象,不需要使用new。例如:

    Biglnt("1234567890") *Biglnt("112358111321")

    像这样使用伴生对象的apply方法是Scala中构建对象的常用手法。例如,Array(l,4,9,16)返回一个数组,用的就是Array伴生对象的apply方法

    Scaladoc

    Java程序员们使用Javadoc来浏览Java AP,Scala也有它自己的版本,叫做Scaladoc。相比Javadoc,浏览Scaladoc更具挑战性。Scala类通常比Java类拥有多得多的便捷方

    法。有些方法使用了你还没学到的特性。而且,有些特性展示出来的是它们的实现细节而并不是使用指南。我们可以在www.scala-lang.org/api在线浏览Scaladoc,不过也可以从www.scala-lang.org/downloads#api下载一个副本安装到本地。

    和Javadoc按照字母顺序列出类清单不同,Scaladoc的类清单按照包排序。如果你知道类名但不知道包名,可以用左上角的过滤器,参照下图:

    点击×号可以清空过滤器。注意每个类名旁边的O和C,它们分别链接到对应的(C)或伴生对象(O)。由于信息量大,Scaladoc可能读起来会比较累人。请记住以下这些小窍门:

    ■ 如果你想使用数值类型,记得看看Richlnt、RichDouble等。同理,如果想使用字符串,记得看看SpringOps

    ■ 那些数学函数位于scala.math包中,而不是位于某个类中

    ■ 有时你会看到名称比较奇怪的函数。比如,Biglnt有一个方法叫做unary_-。这就是你定义前置的负操作符-x的方式

    标记为implicit的方法对应的是自动(隐式)转换。比如,Biglnt对象拥有在需要时自动被调用的由int和long转换为Biglnt的方法

    ■ 方法可以以函数作为参数。例如,StringOps的count方法需要传人一个接受单个Char并返回true或false的函数,用于指定哪些字符应当被清点:

    def count(p: (Char)=>Boolean) : Int

    调用类似方法时,你通常可以一种非常紧凑的表示法给出函数定义。例如,s.count(_.isUpper)的作用是清点所有大写字母的数量 

    ■ 你时不时地会遇到类似RangeSeq[Char]这样的类。它们的含义和你的直觉告诉你的一样:一个是数字区间,一个是字符序列

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
    如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
    如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【Sunddenly】。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    第八章 多线程编程
    Linked List Cycle II
    Swap Nodes in Pairs
    Container With Most Water
    Best Time to Buy and Sell Stock III
    Best Time to Buy and Sell Stock II
    Linked List Cycle
    4Sum
    3Sum
    Integer to Roman
  • 原文地址:https://www.cnblogs.com/sunddenly/p/4402058.html
Copyright © 2011-2022 走看看