2012-07-27 103 views
7

我有库法采取变量参数列表和生产数据斯卡拉隐含带有可变参数列表

class Data 
def process(elems: String*): Data = new Data 

,我想我的琴弦被隐式转换为Data

implicit def strToData(ts: String): Data = process(t) 

,所以我可以写的东西像

val data: Data = "one" 

但我希望元组的字符串是impli也转换了。我已经添加了另一个隐含

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") 

有什么办法来元组隐式转换,或一个原因,它可以取得成就?

更新:元组可以是任何元组。

+2

你确定元组可以是任何元组吗?我认为最高为22(见http://www.scala-lang.org/api/current/scala/Tuple23.html vs http://www.scala-lang.org/api/current/scala/Tuple22.html ) – Martijn 2012-07-27 13:44:52

回答

3

而在@ NikitaVolkov的回答所有的警告在双力适用,您可以编写接受元组的任何参数数量版本,以及任何案例分类:

implicit def prod2data(Product p): process((p.productIterator.toSeq):_*) 
+1

谢谢,我正在寻找什么! – lambdas 2012-07-27 17:15:13

2

您将需要创建从一个元组隐式转换Data

implicit def strTplToData(ts:(String, String)) = process(ts._1, ts._2) 

然后,你可以这样做:

val data: Data = ("one", "two") 
+1

是否有另一种解决方案,而不是为每个元组元数据编写函数? – lambdas 2012-07-27 10:58:52

+1

我不认为有一种简单的实现方法。 – 2012-07-27 11:18:05

5
  1. ts: String*不是一个元组,而是一个Iterable。你不能将iterable转换为元组,因为tuple是一个静态类型,它的arity在编译时被解析。 Emil H回答了你如何从元组中进行隐式转换。
  2. 从一种类型到另一种类型的透明隐式转换是一个常见的陷阱,并且极其令人沮丧。相反,你应该申请一个 “包装” 的方式,或者用 “值类”,因为Scala的2.10:

    在斯卡拉2.9:

    implicit def stringStringTupleExtender (ts : (String, String)) = 
        new { 
        def data = process(ts) 
        } 
    

    在斯卡拉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 
    
  3. 如果你正在寻找动态解决任何输入集合,那么,猜想什么,你应该使用一个集合,而不是一个元组。

    在斯卡拉2。9

    implicit def seqExtender (ts : Seq[String]) = 
        new { 
        def data = process(ts) 
        } 
    

    用法:

    val data : Data = Seq("sdf", "lsdkfjsdl", "ldsfjk").data