Scala不带参数应用

Scala不带参数应用,scala,subclass,apply,Scala,Subclass,Apply,我想创建一个程序,在请求时生成随机的东西,比如下面示例中的字母。我已经定义了一个抽象类和一个伴随对象来返回其中一个子类 abstract class Letter class LetterA extends Letter { override def toString = "A" } class LetterB extends Letter { override def toString = "B" } class LetterC extends Let

我想创建一个程序,在请求时生成随机的东西,比如下面示例中的字母。我已经定义了一个抽象类和一个伴随对象来返回其中一个子类

  abstract class Letter

  class LetterA extends Letter {
    override def toString = "A"
  }
  class LetterB extends Letter {
    override def toString = "B"
  }
  class LetterC extends Letter {
    override def toString = "C"
  }

  object Letter {
    def apply = RNG.d(3) match {
      case 1 => new LetterA
      case 2 => new LetterB
      case 3 => new LetterC
    }
    override def toString = "Random Letter"
  }
我的梦想是,我能够使用
字母
来获得a、B或C类型的随机字母。但使用此代码,它只会给我字母对象<代码>字母。应用给我A、B或C,但很难看

如果我将
apply
函数更改为
apply()
,那么情况会好一些,因为我可以使用
Letter()
来获取一个随机字母,但是
Letter
仍然给我对象


我能做些什么,以便将某些内容分配给
字母
实际上解决了
字母a
字母B
字母C

您的问题的答案是否定的,您无法区分Letter.type和Letter.apply,因此您需要解决方法

我建议您对它使用类型类模式,它比向伴随对象添加随机生成的apply方法更具扩展性

  trait RandomGenerator[T] {
    def gen: T        
  } 

  implicit object RandomLetter extends RandomGenerator[Letter] {

    private val rnd = new Random()

    def gen = (rnd.nextInt(3) + 1) match {
      case 1 => new LetterA
      case 2 => new LetterB
      case 3 => new LetterC
    }
  }

  def random[T: RandomGenerator]: T = 
    implicitly[RandomGenerator[T]].gen


  println(random[Letter])
  println(random[Letter])
  println(random[Letter])

您可以提供从
字母的隐式转换。在伴随对象中键入
字母的转换:

implicit def asLetter(companion: Letter.type): Letter = companion.apply
然后,您可以使用
Letter
获取可以隐式转换为
Letter
类的对象。例如:

val x: Letter = Letter
val letters: Seq[Letter] = Seq.fill(10)(Letter)
但请记住,通过这种方式,您必须始终将对象归于正在使用的类


注意:我不认为这是一个特别好的主意,但我只是想表明这是可能的

您可以将
字母
转换为
def
(如有必要,在package对象上)。为简单起见,我将事物包装在外部对象中:

object Letters {
  // Your class definitions
  def Letter = RNG.d(3) match {
    case 1 => new LetterA
    case 2 => new LetterB
    case 3 => new LetterC
  }
}

使用带有大写名称的
def
不是很习惯用法,但出于某些DSL的考虑,我可以接受。

不。您如何区分类型和方法?