了解Scala中的一些和选项

时间:2018-04-20 15:17:51

标签: scala

我正在从他们的docs

中读到这个例子
class Email(val username: String, val domainName: String)

object Email {
  def fromString(emailString: String): Option[Email] = {
    emailString.split('@') match {
      case Array(a, b) => Some(new Email(a, b))
      case _ => None
    }
  }
}

println(Email.fromString("scala.center@epfl.ch"))
val scalaCenterEmail = Email.fromString("scala.center@epfl.ch")
scalaCenterEmail match {
  case Some(email) => println(
    s"""Registered an email
       |Username: ${email.username}
       |Domain name: ${email.domainName}
     """)
  case None => println("Error: could not parse email")
}

我的问题:

  1. 什么是SomeOption

  2. 什么是工厂方法(只是一些创建新对象并返回它的函数?)

  3. 伴侣物品有什么意义?是否只包含可用于所有类实例的函数?他们喜欢Ruby中的类方法吗?

2 个答案:

答案 0 :(得分:7)

  

什么是部分和选项?

Option是一个代表可选性的数据结构,顾名思义。每当计算可能不返回值时,您都可以返回OptionOption有两种情况(表示为两个子类):SomeNone

在上面的示例中,方法Email.fromString可能会失败,并且不会返回值。这用Option表示。为了了解计算是否产生了值,您可以使用match并检查它是Some还是None

Email.fromString("scala.center@epfl.ch") match {
  case Some(email) => // do something if it's a Some
  case None => // do something it it's a None
}

这比返回null要好得多,因为现在调用该方法的人都可能忘记检查返回值。

比较一下:

def willReturnNull(s: String): String = null

willReturnNull("foo").length() // NullPointerException!

用这个

def willReturnNone(s: String): Option[String] = None

willReturnNone("foo").length() // doesn't compile, because 'length' is not a member of `Option`

另请注意,使用match只是使用Option的一种方式。进一步的讨论将涉及使用mapflatMapgetOrElseOption上定义的类似方法,但我觉得这将是偏离主题的。

  

什么是工厂方法(只是一些创建新对象并返回它的函数?)

这与Scala无关。 A"工厂方法"通常是一个静态方法,它构造某种类型的值,可能隐藏类型本身的细节。在这种情况下,fromString是一种工厂方法,因为它允许您创建Email而无需使用Email

调用new Email(...)构造函数
  

伴侣物品有什么意义?是否只包含可用于所有类实例的函数?他们喜欢Ruby中的类方法吗?

作为第一个近似值,是的。 Scala没有类的静态成员。相反,您可以将object与该类相关联,您可以在其中定义静态的所有内容。

E.g。在Java中你会有:

public class Email {
   public String username;
   public String domain;
   public static Optional<Email> fromString(String: s) {
      // ...
   }
}

在Scala中,您将大致定义相同的类:

class Email(val username: String, val domain: String)
object Email {
  def fromString(s: String): Option[Email] = {
    // ...
  }
}

答案 1 :(得分:0)

我想在第三个问题中添加一些示例/信息。

如果在伴侣对象中使用akka,则可以在case方法中放置您使用的每条消息(它应该由actor继续使用)。此外,您可以为actor的名称或其他常量值添加一些val。

如果您使用JSON,您应该为它创建一种格式(有时是自定义读取和写入)。这种格式你应该放在伴侣对象里面。创建实例的方法。

如果你更深入Scala,你可以找到case classes。因此,在没有new的情况下创建此类的对象的可能性是因为有一个方法适用于&#34;默认&#34; companion object

但总的来说,它是一个可以放置每个静态的地方。方法等。

关于Option,它为您提供了避免某些例外的可能性,并在您没有​​任何价值时制作一些内容。 Gabriele用电子邮件举了一个例子,所以我再添加一个。 您有一种发送电子邮件的方法,但您从User班级收到电子邮件。用户可以将此字段设为空,因此如果我们有类似的话 val maybeEmail: Option[String] = user.email您可以使用例如map来发送电子邮件 maybeEmail.map(email => sendEmail(email))

因此,如果您使用它,在编写上述方法时,您不需要认为用户是否指定了他的电子邮件:)