小鹏闲话
小鹏闲话

不自由,仍可活


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 心路之旅

  • Scala 之旅

  • 搜索

Scala之旅——for解析式

发表于 2018-09-04 分类于 翻译
本文字数: 1.5k 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/for-comprehensions.html

Scala为了表达序列解析提供了一种轻量级的符号。解析式的形式如for (enumerators) yield e,其中enumerators是以分号分隔的枚举器列表。一个枚举器要么是产生新变量的生成器,要么是一个过滤器。解析式对于由枚举器生成的每一个绑定的主体e进行赋值,并且返回这些值的一个序列。

下面是示例:

1
2
3
4
5
6
7
8
9
10
11
case class User(val name: String, val age: Int)

val userBase = List(new User("Travis", 28),
new User("Kelly", 33),
new User("Jennifer", 44),
new User("Dennis", 23))

val twentySomethings = for (user <- userBase if (user.age >=20 && user.age < 30))
yield user.name // i.e. add this to a list

twentySomethings.foreach(name => println(name)) // prints Travis Dennis

这里的for循环使用了yield语句会生成一个List。因为这里的yield user.name是一个List[String]。user <- userBase是一个生成器,而if (user.age >=20 && user.age < 30)是一个守卫,用于过滤出20多岁的用户。

阅读全文 »

Scala之旅——泛型类

发表于 2018-09-02 分类于 翻译
本文字数: 1.1k 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/generic-classes.html

泛型类是接受类型作为参数的类。这对于集合类特别有用。

定义一个泛型类

泛型类使用方括号[]接受类型作为参数。尽管可以使用任何参数名,但是一般约定使用字母A来作为类型参数标识符。

1
2
3
4
5
6
7
8
9
10
class Stack[A] {
private var elements: List[A] = Nil
def push(x: A) { elements = x :: elements }
def peek: A = elements.head
def pop(): A = {
val currentTop = peek
elements = elements.tail
currentTop
}
}

这里Stack类的实现接受任意类型A作为参数。这意味着下面的列表var elements: List[A] = Nil,只能存储A类型的元素。方法def push仅仅接受类型A的参数(注意: elements = x :: elements 通过将x加到当前这个elements的头部,来将elements重新分配到一个新的列表)。

阅读全文 »

Scala之旅——提取器对象

发表于 2018-08-31 分类于 翻译
本文字数: 1.5k 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/extractor-objects.html

一个提取器对象会有一个unapply方法。apply方法类似于接受参数并创建对象的构造器,反过来unapply则是接受一个对象并试图返回原来的参数。这一点在模式匹配和偏函数中经常使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import scala.util.Random

object CustomerID {

def apply(name: String) = s"$name--${Random.nextLong}"

def unapply(customerID: String): Option[String] = {
val stringArray: Array[String] = customerID.split("--")
if (stringArray.tail.nonEmpty) Some(stringArray.head) else None
}
}

val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
customer1ID match {
case CustomerID(name) => println(name) // prints Sukyoung
case _ => println("Could not extract a CustomerID")
}

apply方法由一个name创建了一个CustomerID字符串。unapply则反过来获得了name。当我们调用CustomerID("Sukyoung")时,其实是CustomerID.apply("Sukyoung")的一种简写形式。而当我们调用case CustomerID(name) => println(name)时,则实际调用的是unapply方法。

阅读全文 »

Scala之旅——正则表达式模式

发表于 2018-08-30 分类于 翻译
本文字数: 1.3k 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/regular-expression-patterns.html

正则表达式是一个字符串,可以被用来在数据中查找某种模式(或者没有该模式)的数据。任何字符串只要使用了.r方法就可以转化为一个正则表达式。

1
2
3
4
5
6
7
8
import scala.util.matching.Regex

val numberPattern: Regex = "[0-9]".r

numberPattern.findFirstMatchIn("awesomepassword") match {
case Some(_) => println("Password OK")
case None => println("Password must contain a number")
}

上述例子当中,numberPattern是一个Regex(正则表达式),可以用来确定密码中是否包含数字。
你可以使用圆括号来搜索正则表达式组。

阅读全文 »

Scala之旅——单例对象

发表于 2018-08-30 分类于 翻译
本文字数: 2.4k 阅读时长 ≈ 2 分钟
原文:https://docs.scala-lang.org/tour/singleton-objects.html

对象是只有一个实例的类。当它被引用的时候才会被惰性创建,就像一个惰性的val。

作为顶层值,对象是单例的。

不论作为封闭类成员还是本地值,它表现得完全像一个惰性的val。

定义一个单例对象

对象是一个值。对象的定义跟类差不多,只不过使用的关键字是object:

1
object Box

下面是带方法的对象的例子:

1
2
3
4
5
package logging

object Logger {
def info(message: String): Unit = println(s"INFO: $message")
}

方法info可以在程序的任何位置导入使用。创建这样的工具方法是单例对象的常见用法。

让我们看下如何在另外一个包里使用info方法:

阅读全文 »

Scala之旅——模式匹配

发表于 2018-08-28 分类于 翻译
本文字数: 4.4k 阅读时长 ≈ 4 分钟
原文:https://docs.scala-lang.org/tour/pattern-matching.html

模式匹配是检查一个值是否匹配某种模式的机制。一个成功的匹配可以把一个值解析成它的组成部分。它相当于Java中switch的增强版,可以以此来替代一堆的if/else语句。

语法

一个match表达式有个待匹配的值、match关键字以及至少一个case从句。

1
2
3
4
5
6
7
8
9
10
import scala.util.Random

val x: Int = Random.nextInt(10)

x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "many"
}

上面的val x是0到10之间的要给随机整数。x是match操作符的左操作数,右边是4个样例组成的表达式。最后一个样例_匹配了大于2的所有数字。这些样例也被称为_代值_。

阅读全文 »

Scala之旅——样例类

发表于 2018-08-13 分类于 翻译
本文字数: 1.6k 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/case-classes.html

样例类就像普通类,但是有一些关键的区别,我们后面会提到。样例类很擅长构建不可变数据。接下来,我们会发现它们在模式匹配中很有用。

定义一个样例类

一个最简化的样例类需要关键字case class、标识符以及一个参数列表(也有可能是空的)。

1
2
3
case class Book(isbn: String)

val frankenstein = Book("978-0486282114")

注意这里实例化样例类Book时并没有使用关键字new。这是因为样例类默认有一个apply方法来构造对象。

阅读全文 »

Scala之旅——嵌套方法

发表于 2018-08-12 分类于 翻译
本文字数: 387 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/nested-functions.html

在Scala中,可以定义嵌套方法。下面的例子中,提供了一个方法factorial用于计算给定数字的阶乘: def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x ...

阅读全文 »

Scala之旅——高阶函数

发表于 2018-08-12 分类于 翻译
本文字数: 3k 阅读时长 ≈ 3 分钟
原文:https://docs.scala-lang.org/tour/higher-order-functions.html

高阶函数使用其他函数作为参数,或者返回一个函数。这是可行的,因为在Scala中函数是“头等公民”。关于这点在术语上可能让人有点困惑,我们把那些使用函数作为参数或者返回函数的方法和函数都称为“高阶函数”。

最常见的例子之一是用于Scala中集合的高阶函数map。

1
2
3
val salaries = Seq(20000, 70000, 40000)
val doubleSalary = (x: Int) => x * 2
val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000)

doubleSalary是一个接收Int类型的x,返回x*2的函数。箭头=>左侧的元组是一个参数列表,右侧是返回值。第三行,函数doubleSalary 被应用于列表salaries中的每一个元素。

阅读全文 »

Scala之旅——混入

发表于 2018-08-12 分类于 翻译
本文字数: 1.5k 阅读时长 ≈ 1 分钟
原文:https://docs.scala-lang.org/tour/mixin-class-composition.html

当某个特质被用于组合类时,被称为混入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class A {
val message: String
}
class B extends A {
val message = "I'm an instance of class B"
}
trait C extends A {
def loudMessage = message.toUpperCase()
}
class D extends B with C

val d = new D
println(d.message) // I'm an instance of class B
println(d.loudMessage) // I'M AN INSTANCE OF CLASS B

类D有一个父类B和一个混入C。一个类只能有一个父类但是可以有多个混入(分别使用关键字extend和with)。混入和某个父类可能有相同的父类。

阅读全文 »

1234…24
小鹏

小鹏

238 日志
7 分类
111 标签
RSS
GitHub 知乎
Creative Commons
推荐阅读
  • 心路之旅
  • Scala 之旅
© 2014 – 2019 小鹏 | 站点总字数: 336k | 站点阅读时长 ≈ 5:06
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Muse v7.2.0
|
0%