例如,我有以下函数连接开头和结尾,产生所有可能的连接变体:
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功能?
答案 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
}
人们会试着告诉你这涉及到反思。令人惊讶的是,它没有。