Scala私有申请方法?

时间:2018-08-10 16:32:09

标签: scala methods apply private

我目前正在开设可以存储英语单词的课程。我想使其尽可能安全(如果输入无效-返回错误消息),这是我迷路的地方。我有存储英语单词的这段代码:

  case class English_LT_Word private (word: String)
  object English_LT_Word {
    def apply(word: String) = new English_LT_Word(word)
    def createNewWord(word: String): Either[String, English_LT_Word] = {
      if (word.length > 0 && word.forall(x=>consonants.contains(x) || vowels.contains(x))) Right(apply(word))
      else Left("'" + word + "'" + " is an invalid word")
    }
  }

在此示例中,我可以创建任何这样的英语单词:

val english = English_LT_Word.apply("Awesome")
val english = English_LT_Word.createNewWord("Awesome")

在这里,我对要使用的内容感到困惑,这并不漂亮。如何正确执行此操作?将.apply()方法设为私有是不可能的,因为(长话短说)编译器将不同步。我只想使用.createNewWord()方法来创建我的单词。有什么想法吗?

谢谢!! ^^

3 个答案:

答案 0 :(得分:3)

您可以使用-Xsource:2.12在2.12或2.11下定义自定义案例伴侣。

$ ~/scala-2.11.12/bin/scala -Xsource:2.12 
cat: /usr/lib/jvm/jdk1.8.0/release: No such file or directory
Welcome to Scala 2.11.12 (OpenJDK 64-Bit Server VM, Java 1.8.0_181).
Type in expressions for evaluation. Or try :help.

scala> :pa
// Entering paste mode (ctrl-D to finish)

import scala.util._

case class Word private (text: String)
object Word {
  def apply(s: String): Either[String, Word] =
    if (s.nonEmpty) Right(new Word(s)) else Left("Empty word!")
}

// Exiting paste mode, now interpreting.

import scala.util._
defined class Word
defined object Word

scala> Word("")
res0: scala.util.Either[String,Word] = Left(Empty word!)

scala> Word("ok")
res1: scala.util.Either[String,Word] = Right(Word(ok))

答案 1 :(得分:2)

使用伴随对象创建一个简单的类,该对象可以创建EnglishWord的正确实例

必须使用伴随对象创建实例。如果您使用new关键字直接创建实例,则编译器不允许

class EnglishWord private (word: String)

object EnglishWord {

 def createEnglishWord(word: String): Either[String, EnglishWord] = {

  if (word.length > 0 &&
    word.forall(x => consonants.contains(x) || vowels.contains(x)))
    Right(new EnglishWord(word))
  else Left("'" + word + "'" + " is an invalid word")

 }

}

答案 2 :(得分:2)

我几乎会做你已经在做的事情,但是不适用...

class English_LT_Word private (word: String)

object English_LT_Word {
  def create(word: String): Either[String, English_LT_Word] = {
    if (word.length > 0 && word.forall(x=>consonants.contains(x) || vowels.contains(x)))
      Right(new English_LT_Word(word))
    else
      Left("'" + word + "'" + " is an invalid word")
  }
}

,或者您可以模仿某些collections API,例如headOption

object English_LT_Word {
  private def isValidWord(s: String) = !s.isEmpty && s.toLowerCase.forall(('a' to 'z').contains)

  def createOption(word: String): Option[English_LT_Word] = {
    if isValidWord(word) Some(new English_LT_Word(word)) else None
  }
}

然后行为就很清楚了(我可以自由地修改验证,如果愿意,可以忽略)