具有类型参数的类的Scala隐式类型转换

时间:2015-06-10 16:47:19

标签: scala type-conversion implicit-conversion

我正在尝试为scala.collection.Iterable特性添加功能,更具体地说,是一个打印元素并打印出来的打印函数(如果没有参数则输出到控制台,否则输出到输出流参数) 。我正在使用我为object,printSelf()创建的预定义扩展方法。但是,这会导致编译器错误,'值printSelf不是类型参数Object的成员。我还希望将它作为一个单独的文件,这样我就可以在多个项目和应用程序之间轻松使用。

这是我转换文件的当前代码:

collect

我在尝试测试它的代码中也遇到了类似的错误,'value printerate不是scala.collection.immutable.Range的成员':

import java.io.OutputStream
import scala.collection.Iterable

package conversion{
  class Convert {
    implicit def object2SuperObject(o:Object) = new ConvertObject(o)
    implicit def iterable2SuperIterable[Object](i:Iterable[Object]) = new ConvertIterable[Object](i)
  } 
  class ConvertObject(o:Object){
    def printSelf(){
      println(o.toString())
    }
    def printSelf(os:OutputStream){
      os.write(o.toString().getBytes())
    }
  }
  class ConvertIterable[Object](i:Iterable[Object]){
    def printerate(){
      i.foreach {x => x.printSelf() }
    }
    def printerate(os:OutputStream){
      i.foreach { x => x.printSelf(os) }
    }
  }
}

我正在接近这种类型转换的方式有什么问题?

1 个答案:

答案 0 :(得分:2)

事实上有几件事:

  1. 转换应该是一个对象,而不是一个类。
  2. 您使用Object代替Any
  3. 您使用Object作为通用类型标识符,而不是使用较少混淆的T。
  4. 您不导入隐式定义(它不足以导入对象本身)。
  5. 这应该有效:

    package conversion {
      object Convert {
        implicit def object2SuperObject(o: Any) = new ConvertObject(o)
        implicit def iterable2SuperIterable[T](i:Iterable[T]) = new ConvertIterable[T](i)
      } 
      class ConvertObject(o: Any){
        def printSelf(){
          println(o.toString())
        }
        def printSelf(os:OutputStream){
          os.write(o.toString().getBytes())
        }
      }
      class ConvertIterable[T](i:Iterable[T]){
        import Convert.object2SuperObject
        def printerate(){
          i.foreach {x => x.printSelf() }
        }
        def printerate(os:OutputStream){
          i.foreach { x => x.printSelf(os) }
        }
      }
    }
    
    import conversion.Convert._
    

    第二档:

    package test {
      object program extends App {
        new testObj(10) test
      }
      class testObj(i: Integer) {
        def test(){
          val range = 0.until(i)
          0.until(i).printerate()
        }
      }
    }