这种奇怪的类型[T *]

时间:2010-11-25 11:13:40

标签: scala

例如,我有以下函数连接开头和结尾,产生所有可能的连接变体:

def mixer1(begin: String, beginings: String*)(end: String, endings: String*) =
  for (b <- (begin +: beginings); e <- (end +: endings)) yield (b + e)

实际上什么功能不起作用,我想用这种方式重写:

  def mixer2(begin: String, beginings: String*):Function2[String, Seq[String], Seq[String]] = {
    return new Function2[String, Seq[String], Seq[String]] {
      def apply(end:String, endings:Seq[String]) = for(b <- (begin +: beginings); e <- (end +: endings)) yield b+e
    }
  }

显然,第二个不会按预期工作,因为apply的第二个参数的类型为Seq [String]但不是String *(如果它们都编译为Seq [String]):

scala> mixer1("a","b")("c","d")
res0: Seq[java.lang.String] = ArrayBuffer(ac, ad, bc, bd)

scala> mixer2("a","b")("c","d")
<console>:10: error: type mismatch;
 found   : java.lang.String("d")
 required: Seq[String]
       mixer2("a","b")("c","d")

我如何(如果可以)重新定义mixer2功能?

4 个答案:

答案 0 :(得分:3)

尝试这种方式:

def mixer2(begin: String, beginings: String*) = {
    new ((String, String*) => Seq[String]) {
      def apply(end: String, endings: String*) = for(b <- (begin +: beginings); e <- (end +: endings)) yield b+e
    }
}

我们在mixer2上使用类型推断来获得正确的类型。这意味着必须删除return,但这没关系,因为它是不必要的(并且通常建议不要使用Scala)。最大的诀窍是使用A => B的{​​{1}}句法糖来使用Function。然后按预期更改String*

答案 1 :(得分:2)

你可以轻松一点:

def mixer2 = mixer1 _

答案 2 :(得分:0)

如您的示例所示,您可以执行此操作

implicit def toSeq[T](x: T): Seq[T] = List(x)

但是当谈到更多的论点时,比如

mixer2("a","b")("c","d","e")

似乎没有合适的解决方案,尽管存在从Array [T]到Seq [T]的隐式转换。因为T *是语法糖果,(“c”,“d”,“e”)将被视为3个参数。编译器无法识别哪些形成数组。

所以我想知道你的实际情况是什么,这个例子看起来很奇怪。 如果你只想要一部分功能,@ Debilski的解决方案是一个很好的方法。

答案 3 :(得分:0)

您甚至无需命名中间返回类型即可进行转义。

def mixer2(begin: String, beginings: String*) = new {
  def apply(end: String, endings: String*) =
    for (b <- (begin +: beginings); e <- (end +: endings)) yield b+e
}

人们会试着告诉你这涉及到反思。令人惊讶的是,它没有。