【Scala之旅】基础知识
简介欢迎光临此旅途包含了一些精简的介绍:介绍Scala最常用的功能。它旨在帮助新手学习这门语言。 这只是一个简短的介绍,而不是一个完整的语言教程。如果可以的话,考虑买本书或查阅其他资源。 什么是Scala?Scala是一种现代多范式编程语言,旨在以简洁,优雅和类型安全的方式表达常见的编程模式。它平滑地集成了面向对象和函数式语言的特性。 Scala是面向对象语言Scala是一个纯面向对象语言,在某种意义上来讲所有值都是对象。对象的类型和行为是由类和特质来描述的。类通过子类化和灵活的基于混入的组合机制扩展为多重继承的完全替代。 Scala是函数式语言Scala还是一个函数式语言,在某种意义上来讲所有函数都是值。Scala提供了轻量级的语法来定义匿名函数,它支持高阶函数,允许函数嵌套,并支持柯里化。Scala的样例类及其对模式匹配模型代数类型的内置支持,用于许多函数式编程语言。单例对象提供了一种便捷的方法来对不是类成员的函数进行分组。 此外,Scala的模式匹配概念自然延伸到借助于忽略右序列模式的XML数据处理,通过通过提取器对象进行的一般扩展。在这种情况下,for推导式有助于制定查询。这些功能使Scala成为开发Web服务等应用程序的理想选择。 Scala是静态类型语言Scala配备了一种表达型系统,可以静态强制执行以安全和一致的方式使用抽象。具体来说,该类型系统支持:
类型推断意味着用户不需要使用冗余类型信息注释代码。终上所述,这些特性为编程抽象的安全重用和软件的类型安全扩展提供了强大的基础。 Scala是可扩展的在实践中,特定领域应用程序的开发通常需要特定领域的语言扩展。Scala提供了独特的语言机制组合,可以方便地以库的形式顺利地添加新的语言结构。 在许多情况下,这可以在不使用宏等元编程工具的情况下完成。例如:
Scala是可互操作的Scala旨在与流行的Java运行时环境(JRE)良好地互操作。特别是与主流面向对象的Java编程语言的交互尽可能平滑。较新的Java功能(如SAM,lambda,注解和泛型)在Scala中具有直接类似功能。 那些没有Java类似物的Scala特性,如默认参数和带名参数,尽可能接近Java地进行编译。Scala与Java一样具有相同的编译模型(单独编译,动态类加载),并允许访问数千个现有的高质量库。 基础在浏览器中尝试Scala你可以在浏览器中的ScalaFiddle运行Scala。
这是一个简单的,零设置的方式来测试Scala代码片段。 表达式表达式是可计算的语句。 1 + 1 你可以使用 println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! println("Hello," + " world!") // Hello,world! 值你可以使用 val x = 1 + 1println(x) // 2 命名结果,比如这里的 值不能被重新分配。 val x = 1 + 1x = 3 // This does not compile. 编译器可以推断出类型的值,但是您也可以显式地声明类型,如下所述: val x: Int = 1 + 1 注意,类型声明 变量变量就像值,但你可以重新分配它们。你可以使用 var x = 1 + 1x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 与值一样,你可以显式地声明类型: var x: Int = 1 + 1 代码块你可以把周围的表达式结合起来。我们称这个为代码块。 块的最后一个表达式的结果也是整个块的结果。 println({ val x = 1 + 1 x + 1 }) // 3 函数函数是带参数的表达式。 你可以定义一个匿名函数(也就是没有名称),它返回一个给定的整数+1: (x: Int) => x + 1 在推出符号 你也可以命名函数。 val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 函数可以使用多个参数。 val add = (x: Int,y: Int) => x + y println(add(1,2)) // 3 或者它不需要参数。 val getTheAnswer = () => 42 println(getTheAnswer()) // 42 方法方法看起来和函数非常相似,但是它们之间有一些关键的区别。 方法使用 def add(x: Int,y: Int): Int = x + y println(add(1,2)) // 3 注意返回类型是在参数列表和冒号 方法可以使用多个参数列表。 def addThenMultiply(x: Int,y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1,2)(3)) // 9 或者根本没有参数列表。 def name: String = System.getProperty("name") println("Hello," + name + "!") 还有一些其他的区别,但是现在,你可以把它们看作是类似于函数的东西。 方法也可以有多行表达式。 def getSquareString(input: Double): String = { val square = input * input square.toString }
类你可以使用类关键字 class Greeter(prefix: String,suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) } 方法 你可以使用关键字 val greeter = new Greeter("Hello,","!") greeter.greet("Scala developer") // Hello,Scala developer! 之后我们将详细介绍类。 样例类Scala有一种特殊类型的类,称为“样例”类。默认情况下,样例类是不可变的,并按值进行比较。 你可以用 case class Point(x: Int,y: Int) 您可以不需要使用 val point = Point(1,2) val anotherPoint = Point(1,2) val yetAnotherPoint = Point(2,2) 它们是按值进行比较的。 if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { println(point + " and " + anotherPoint + " are different.") } // Point(1,2) and Point(1,2) are the same. if (point == yetAnotherPoint) { println(point + " and " + yetAnotherPoint + " are the same.") } else { println(point + " and " + yetAnotherPoint + " are different.") } // Point(1,2) and Point(2,2) are different. 我们想要介绍的样例类还有很多,我们相信你会爱上它们的!之后我们将详细介绍它们。 对象对象是它们自己定义的单个实例。你可以把他们想象成他们自己的类的单例。 你可以通过使用关键字 object IdFactory { private var counter = 0 def create(): Int = { counter += 1 counter } } 你可以通过引用对象名来访问一个对象。 val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() println(newerId) // 2 稍后我们将详细介绍对象。 特质特征是包含某些字段和方法的类型。多个特征可以组合在一起。 你可以通过使用关键字 trait Greeter { def greet(name: String): Unit } 特征也可以有默认的实现。 trait Greeter { def greet(name: String): Unit = println("Hello," + name + "!") } 您可以使用 class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String,postfix: String) extends Greeter { override def greet(name: String): Unit = { println(prefix + name + postfix) } } val greeter = new DefaultGreeter() greeter.greet("Scala developer") // Hello,Scala developer! val customGreeter = new CustomizableGreeter("How are you,"?") customGreeter.greet("Scala developer") // How are you,Scala developer? 在这里, 稍后我们将详细介绍特质。 主方法主方法是一个程序的入口点。Java虚拟机需要一个命名为 使用对象,您可以定义一个主方法,如下: object Main { def main(args: Array[String]): Unit = println("Hello,Scala developer!") } 统一类型在Scala中,所有值都有一个类型,包括数值和函数。下图演示了类型层次结构的一个子集。 Scala类型层次结构
这里有一个例子,它演示了字符串、整数、字符、布尔值和函数都是与其他对象一样的对象: val list: List[Any] = List( "a string",732,// an integer 'c',// a character true,// a boolean value () => "an anonymous function returning a string" ) list.foreach(element => println(element)) 它定义了类型 下面是程序的输出: a string 732 c true <function> 类型转换值类型可以通过以下方式进行转换: 例如: val x: Long = 987654321 val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) val face: Char = '?' val number: Int = face // 9786 转换是单向的。下面最后一条语句将无法通过编译: val x: Long = 987654321 val y: Float = x // 9.8765434E8 val z: Long = y // Does not conform 你还可以将引用类型转换为子类型。这将在之后的文章中被介绍。 Nothing和Null
包和引入Scala使用包创建命名空间,允许您对程序进行模块化。 创建package通过 在Scala 文件的顶部声明一个或多个包名称来创建包。 package users class User 一个约定是将包命名为与包含 Scala 文件的目录相同。但是,Scala 不知道文件的布局。包用户的 sbt 项目的目录结构可能如下所示: - ExampleProject - build.sbt - project - src - main - scala - users User.scala UserProfile.scala UserPreferences.scala - test 注意 package users { package administrators { class NormalUser } package normalusers { class NormalUser } } 正如您所看到的,这允许封装嵌套并为范围和封装提供更好的控制。 软件包名称应全部小写,如果代码是在具有网站的组织内开发的,则应采用以下格式约定: package com.google.selfdrivingcar.camera class Lens 这可以对应于以下目录结构:
引入
import users._ // import everything from the users package import users.User // import the class User import users.{User,UserPreferences} // Only imports selected members import users.{UserPreferences => UPrefs} // import and rename for convenience Scala与Java不同的一个方法是可以在任何地方使用 def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 } 如果存在命名冲突,并且需要从项目的根目录导入某些内容,请在 package accounts import __root__.users._ 注意:默认情况下导入 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |