Scala 隐式转换和箭头
scala implicit convertion and arrow
我正在为我的 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)
}
有什么想法吗?
通过隐式转换(any2ArrowAssoc
in scala.Predef
),->
方法可用于所有 Scala 类型。出于理智的原因,Scala 不允许在同一表达式上对 "chain" 进行多次隐式转换。你可以:
- 在您的
A
class 上定义一个明确的 ->
方法。不幸的是,由于默认的隐式转换会与此冲突,因此您可能必须使用 -Yno-predef
构建代码以避免冲突
- 在您的
A
class 上定义一个方法,其名称在外观上相似且不冲突,例如~>
或 »
- 如果您喜欢这种语法,请调用
myMethod(("a", "b"))
(直接支持这种语法,而不是通过隐式转换)
- 让
myMethod
接受(String, String)*
并在里面做A
和B
的转换
- 编辑:您还可以按照@BenReich 的建议定义从
(String, String)
到(A, B)
的隐式转换。
您可以定义从 (String, String) 到 (A, B) 的隐式转换:
implicit def toABTuple(in: (String, String)) = (A(in._1), B(in._2))
它失败了,因为它在应用你的隐含函数之前转换为一个元组,所以它不再是一个普通的字符串 -> A/B。
我正在为我的 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)
}
有什么想法吗?
通过隐式转换(any2ArrowAssoc
in scala.Predef
),->
方法可用于所有 Scala 类型。出于理智的原因,Scala 不允许在同一表达式上对 "chain" 进行多次隐式转换。你可以:
- 在您的
A
class 上定义一个明确的->
方法。不幸的是,由于默认的隐式转换会与此冲突,因此您可能必须使用-Yno-predef
构建代码以避免冲突 - 在您的
A
class 上定义一个方法,其名称在外观上相似且不冲突,例如~>
或»
- 如果您喜欢这种语法,请调用
myMethod(("a", "b"))
(直接支持这种语法,而不是通过隐式转换) - 让
myMethod
接受(String, String)*
并在里面做A
和B
的转换 - 编辑:您还可以按照@BenReich 的建议定义从
(String, String)
到(A, B)
的隐式转换。
您可以定义从 (String, String) 到 (A, B) 的隐式转换:
implicit def toABTuple(in: (String, String)) = (A(in._1), B(in._2))
它失败了,因为它在应用你的隐含函数之前转换为一个元组,所以它不再是一个普通的字符串 -> A/B。