scala隐式转换和箭头

时间:2015-02-27 14:04:33

标签: scala implicit-conversion

我正在努力完成我的DSL建设尝试

我的方法应该采用多对(A,B),理想情况下我会寻找这种代码:

myMethod(
  a1 -> b1,
  a2 -> b2,
  a3 -> b3)

我的A和B类经常使用单个字符串参数构造,所以我添加了隐式转换器,如下所示:

implict def stringToA(s: String): A = new A(s)
implict def stringToB(s: String): B = new B(s)

但是箭头操作符(对于结构构造)并没有获取隐式转换器:

object Test {
  case class A(s: String)
  case class B(s: String)

  def myMethod(pairs: (A, B)*): Unit = Unit

  implicit def stringToA(s: String): A = A(s)
  implicit def stringToB(s: String): B = B(s)

  myMethod(new Tuple2("a", "b")) // works just fine
  myMethod("a" -> "b") // Error: Type mismatch, expected: (Test.A, Test.B), actual: (String, String)
}

任何想法?

2 个答案:

答案 0 :(得分:5)

->方法通过隐式转换(any2ArrowAssoc中的scala.Predef)在所有Scala类型上可用。出于理智的原因,Scala不允许多次隐式转换为"链"在同一个表达。你可以:

  • ->课程中定义明确的A方法。不幸的是,由于默认的隐式转换会与此冲突,因此您可能必须使用-Yno-predef构建代码以避免冲突
  • A课程中定义一个方法,其名称视觉上相似且不会发生冲突,例如: ~>»
  • 如果你喜欢这种语法,请调用myMethod(("a", "b"))(直接支持此语法,而不是通过隐式转换支持)
  • myMethod接受(String, String)*并转换为内部的AB
  • 编辑:您也可以定义从(String, String)(A, B)的隐式转换,如@BenReich所示。

答案 1 :(得分:0)

您可以定义从(String,String)到(A,B)的隐式转换:

implicit def toABTuple(in: (String, String)) = (A(in._1), B(in._2))   

它失败了,因为它在应用你的implicits之前转换为元组,所以它不是一个普通的字符串 - > A / B了。