代码之家  ›  专栏  ›  技术社区  ›  I82Much

scala-当一个参数必须为空时,如何显式选择要使用的重载方法?

  •  8
  • I82Much  · 技术社区  · 15 年前

    所有的,

    我在scala中利用bufferedimages和光栅对象进行一些图像处理。我试图用以下代码获取缓冲图像中的所有像素。

    val raster = f.getRaster()
    
    // Preallocating the array causes ArrayIndexOutOfBoundsException .. http://forums.sun.com/thread.jspa?threadID=5297789
    // RGB channels;
    val pixelBuffer = new Array[Int](width*height*3)
    val pixels = raster.getPixels(0,0,width,height,pixelBuffer)
    

    现在,当我读取相对较大的文件时,这很好。当我读取20x20 PNG文件时,我得到一个arrayindexoutofboundsException:

    java.lang.ArrayIndexOutOfBoundsException: 1200
    at sun.awt.image.ByteInterleavedRaster.getPixels(ByteInterleavedRaster.java:1050)
    

    我读过 online 解决这个问题的方法不是预先分配PixelBuffer,而是传递一个空值,并使用由graster.getPixels方法返回的值。

    这是我的问题。当我采用幼稚的方法,把零作为最后一个论点:

    val pixels = raster.getPixels(0,0,width,height,Nil)
    

    我得到错误

    error: overloaded method value getPixels with alternatives (Int,Int,Int,Int,Array[Double])Array[Double] <and> (Int,Int,Int,Int,Array[Float])Array[Float] <and> (Int,Int,Int,Int,Array[Int])Array[Int] cannot be applied to (Int,Int,Int,Int,Nil.type)
    val pixels = raster.getPixels(0,0,width,height,Nil)
    

    很明显,编译器无法确定我要调用的两个方法中的哪一个;这是不明确的。如果我使用Java,我将抛出NULL使我的意图明确。我不太明白如何在scala中获得同样的效果。我尝试过的事情:

     val pixelBuffer:Array[Int] = Nil // Cannot instantiate an Array to Nil for some reason
     Nil.asInstanceOf(Array[Int]) // asInstanceOf is not a member of Nil
    

    你知道如何明确地告诉编译器我想要用int数组作为最后一个参数而不是浮点数组的方法吗?

    编辑: 正如一个答案指出的那样,我得到的是零和零。nil是一个空列表。请参阅以下内容 blog post

    另外,我应该指出数组越界异常是我的错(正如这些事情经常发生的那样)。问题是我假设光栅有3个通道,但我的图像有4个通道,因为我是这样创建的。我改为按如下方式预分配阵列:

    val numChannels = raster.getNumBands() 
    
    val pixelBuffer = new Array[Int](width*height*numChannels)
    val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)
    

    谢谢你的帮助

    2 回复  |  直到 15 年前
        1
  •  16
  •   Randall Schulz    15 年前

    (假设您希望在需要传递空值时如何解决重载问题):

    正如您在Java中所做的那样,通过输入与您希望调用的重载对应的类型(在爪哇中,您将抛出,但它等于相同的东西:一个静态类型的断言来分配给 null ):

    scala> object O { def m(i: Int, s: String): String = s * i; def m(i: Int, l: List[String]): String = l.mkString(":") * i }
    defined module O
    
    scala> O.m(23, null)
    <console>:7: error: ambiguous reference to overloaded definition,
    both method m in object O of type (i: Int,l: List[String])String
    and  method m in object O of type (i: Int,s: String)String
    match argument types (Int,Null)
           O.m(23, null)
             ^
    
    scala> O.m(23, null: String)
    res4: String = nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
    
    scala> O.m(23, null: List[String])
    java.lang.NullPointerException
            at O$.m(<console>:5)
            at .<init>(<console>:7)
            at .<clinit>(<console>)
            at RequestResult$.<init>(<console>:9)
            at RequestResult$.<clinit>(<console>)
            at RequestResult$scala_repl_result(<console>)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:981)
            at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:981)
            at scala.util.control.Exception$Catch.apply(Exception.scala:7...
    scala>
    
        2
  •  5
  •   Dimitris Andreou    15 年前

    你困惑 Nil 具有 null .

    推荐文章