user3825558
user3825558

Reputation: 585

Scala: understanding how to make my method return the proper return type of Array

I have written the following Scala code:

class MyTestApi {
     private def toCPArray(inputStr: String): Array[Int] = {
      val len = inputStr.length
    //invoke ofDim of Scala.Array
    val cpArray = Array.ofDim[Int](inputStr.codePointCount(0, len))
    var i = 0
    var j = 0
    while (i < len) {
      cpArray(j += 1) = inputStr.codePointAt(i)
      i = inputStr.offsetByCodePoints(i, 1)
    }
    cpArray
  }           

}

This is what I want to accomplish:

I would create an instance of class MyTestApi and then invoke the method toCPArray and pass to it a parameter of type String. I would then like this method to return me an `Array[Int].

However as it stands now, the Scala IDE is complaining about this line:

**cpArray(j += 1) = inputStr.codePointAt(i)**  

type mismatch; Found: Unit required: Int

Two things I would like to accomplish are:

  1. How would I fix this method? (or is it a function) My hope is, after I understand what it takes to fix this method (or function) I will be able to return the appropriate type. Also, I should be in better position to understand the difference between a method and a function.

So far my research on stackoverflow and Martin Odersky's book seems to suggests to me that what I wrote is a method because it is invokded on an instance of the underlying class. Is my understanding right on that?

  1. After it is fixed, how can i rewrite it in a more Scalaesque way, by getting rid of the var. The code looks more C or java like right now and is a little long in my opinion, after all that I have studied about Scala so far.

Thanks for any help in refactoring the above code to accomplish my learning objectives.

Upvotes: 0

Views: 1627

Answers (2)

pedrofurla
pedrofurla

Reputation: 12783

Many questions in one. I try to answer them all.

First of all as Jörg pointed out, moving the assignment makes the code work. Contrary to Java and C, Scala's assignment doesn't return the assigned value but Unit.

Now for making it idiomatic. Scala's String can be seem as IndexedSeq[Char], meaning you can generally treat them as IndexedSeqs. So you doing do something like:

inputStr.map{ x => x.toInt }.toArray

This will return an Array[Int]. Notice it will only work for 16-bits char representations. Hopefully it will help in giving an idea of idiomatic Scala, even not being a perfect solution.

For the difference between methods and functions, it's simple: methods are generally defs in a class. Functions one the other hands are Objects in the JVM sense. For example, the above map could be defined like:

def map(f: Function1[Char, Int]):IndexedSeq[Int]
// or
def map(f: Char => Int):IndexedSeq[Int]

Both are the same, => desugars to one of the scala.FunctionN (N from 0 to 22 inclusive).

And x => x.toInt is desugared in a similar way into a instance of scala.Function1. See it's Scaladoc.

So, functions are objects of type scala.FunctionN.

Note: to keep things simple I omitted a few details like type parameters, vals (which often compiles to JVM methods) and probably a few more details.

Upvotes: 2

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369458

You are calling cpArray.update with an assignment statement which evaluates to Unit when it expects an Integer. You need to call it with an Integer:

j += 1
cpArray(j) = inputStr.codePointAt(i)

Upvotes: 2

Related Questions