How to Implement Implicit Conversion to Iterable<T>?


#1

I have a BufferedImage for which I wish to implement an Iterable so that I may iterate over all the pixels.

data class Pixel(val point: Point, val color: Color)

fun BufferedImage.iterable(): Iterable<Pixel> {
  return object: Iterable<Pixel> {
  override fun iterator(): Iterator<Pixel> {
           return iterator()
  }
  }
}

fun BufferedImage.iterator(): Iterator<Pixel> {
  return object : Iterator<Pixel> {
  var currentX = 0
  var currentY = 0

  &nbsp;&nbsp;override fun hasNext(): Boolean {

           return currentY != getHeight()
  }

  &nbsp;&nbsp;override fun next(): Pixel {

           val point = Point(currentX, currentY)
           val color = Color(getRGB(currentX, currentY))

           if (currentX == getWidth() - 1) {
           currentX = 0
           currentY += 1
           } else {
           currentX += 1
           }

           return Pixel(point, color)
  }
  }
}

This code let's me write

for (pixel in image) { doStuff(pixel) }

And

image.iterator().map { doStuff(it) } image.iterable().map { doStuff(it) }

But I can't directly write

image.map { doStuff(it) }

Why not? I feel like I'm missing only one more piece and then everything will work as intended.


#2

Kotlin does not support implicit conversions, in fact, this is something we are strongly against. The best we can offer for your case is explicitly calling some method/property before calling map(), e.g.:

image.it.map {...}

where

val BufferedImage.it: Iterable<Pixel>   get() = ...


#3

Small addition, recently something changed and keyword operator is now required for declaration of function iterator() to use it implicitly in for cycles.

operator fun BufferedImage.iterator(): Iterator