0

斯卡拉很酷。但有时也非常令人沮丧,因为许多看似武断的限制以及不像我预期的那样工作的事情。

在这种情况下,我用 Scala 编写了一个参数解析库。它有这个功能:

def option[T](
  name1: String, name2: String = null, name3: String = null,
  name4: String = null, name5: String = null, name6: String = null,
  name7: String = null, name8: String = null, name9: String = null,
  default: T = null.asInstanceOf[T],
  metavar: String = null,
  choices: Seq[T] = null,
  aliases: Map[T, Iterable[T]] = null,
  help: String = "")
(implicit convert: (String, String, ArgParser) => T, m: Manifest[T]) = {
  optionSeq[T](nonNullVals(name1, name2, name3, name4, name5, name6,
    name7, name8, name9),
    metavar = metavar, default = default, choices = choices,
    aliases = aliases, help = help)(convert, m)
}

本质上,这声明了给定类型的普通选项参数。有一个隐式函数,其中填充了适合该类型的默认转换器。还有一个隐含的清单,这是必要的,因为我需要能够在某些事情上以它为条件。

这一直有效,直到我尝试实际提供非默认转换器。正如所写,您不能只提供转换器,还必须提供清单,我不知道该怎么做,而且无论如何它都非常丑陋 - 清单是一个令人讨厌的组合,旨在解决一个主要部分JVM 中的损坏,不应该暴露给最终用户。

我已经知道 Scala 不允许您在单个参数列表中混合隐式和非隐式参数 - IMO 是任意且不必要的限制,但就这样吧。所以我尝试将隐式参数列表拆分为两个单独的参数列表,每个列表都有一个隐式。不走运——Scala 似乎也阻止了你拥有多个隐式参数列表(另一个看似任意的限制)。

我对如何解决这个问题一无所知。建议?

此外,目前是否有任何尝试在未来的 Scala 版本中修复对隐式的一些限制(和/或提出一种比清单更不可见的解决类型擦除损坏的方法,IMO 是丑陋的)?

4

2 回答 2

3

您始终可以在上下文中获取implicitof 类型。因此,如果您需要显式编写编译器将提供的隐式,您可以使用.Timplicitly[T]Manifest[T]implicitly[Manifest[T]]

每当您想在隐式参数列表中提供一个参数并保持另一个不变时,这都可以使用,只需将隐式 [TheTypeOfTheImplicit] 用于您不想更改的参数。

对于 Manifests,Predef恰好有一个捷径,即 just manifest[T](which is just implicitly[Manifest[T]])

注意:implicitly不是魔术,它只是def implicitly[T](implicit e: T) = e, inPredef.

于 2012-05-02T23:56:29.677 回答
3

这是一个非常尴尬的方法。九个显式名称参数?隐式选择转换函数?我不确定清单是这里最严重的问题。

无论如何,你可以

class Converter[T: Manifest](val f: (String, String, ArgParser) => T) {
  def m = manifest[T]
}
implicit def function_to_converter[T: Manifest](f: (String, String, ArgParser) => T) =
  new Converter { def apply(s1: String, s2: String, ap: ArgParser) = f(s1,s2,ap) }
}

然后用它代替你得到的两个论点。定义所有默认转换器,例如

implicit val convert_to_int: Converter = (s1: String, s2: String, ap: ArgParser) => ...

然后如果用户需要显式填写一个,他们可以只提供该函数并对其进行隐式转换。

于 2012-05-03T00:44:47.727 回答