我有使用变量参数列表和生成数据的库方法
class Data
def process(elems: String*): Data = new Data
我想将我的字符串隐式转换为Data
implicit def strToData(ts: String): Data = process(t)
所以我可以写点像
val data: Data = "one"
但我想要隐式转换字符串元组。我添加了另一个隐含的
implicit def strsToData(ts: String*): Data = process(ts: _*)
它编译得很好,但转换失败
val data: Data = ("one", "two")
val dat3: Data = ("one", "two", "three")
val dat4: Data = ("one", "two", "three", "four")
与
found : Seq[java.lang.String]
required: this.Data
val data: Data = Seq("one", "two")
有没有办法隐式转换元组,或者为什么可以实现它?
更新:元组可以是任何元素。
答案 0 :(得分:5)
ts: String*
不是元组,而是Iterable
。你不能将iterable转换为元组,因为tuple是一个静态类型,它的arity在编译时被解析。 Emil H回答了如何从元组进行隐式转换。 从一种类型到另一种类型的透明隐式转换是一个常见的陷阱,并且非常不鼓励。相反,您应该应用“包装器”方法,或者使用Scala 2.10以来的“值类”:
在Scala 2.9中:
implicit def stringStringTupleExtender (ts : (String, String)) =
new {
def data = process(ts)
}
在Scala 2.10中:
implicit class StringStringTupleExtender (val ts : (String, String)) extends AnyVal {
def data = process(ts)
}
然后你会像这样使用它:
val data : Data = ("sdf", "lsdfj").data
val data1 : Data = "sdf".data // if you do the same for String
如果您正在寻找动态解析任何输入集合,那么,猜猜是什么,您应该使用集合,而不是元组。
在Scala 2.9中
implicit def seqExtender (ts : Seq[String]) =
new {
def data = process(ts)
}
用法:
val data : Data = Seq("sdf", "lsdkfjsdl", "ldsfjk").data
答案 1 :(得分:3)
虽然@ NikitaVolkov的答案中的所有警告都是双重的,但你可以编写一个接受任何元组元素的版本,以及任何案例类:
implicit def prod2data(Product p): process((p.productIterator.toSeq):_*)
答案 2 :(得分:2)
您需要创建从元组到Data
的隐式转换:
implicit def strTplToData(ts:(String, String)) = process(ts._1, ts._2)
然后你可以这样做:
val data: Data = ("one", "two")