Dmitry Nogin
Dmitry Nogin

Reputation: 3750

String concatenation in Scala

I have this helper to simplify null asserts:

object Helpers {
  implicit class NotNullAssert[T](val obj: T) extends AnyVal {
    def ! : T = {
      assert(obj != null); obj
    }
  }
}

Now I am trying to use it:

import Helpers._

class Name(val first: String, val last: String) {
  val full = first! + " " + last!
}

Getting a compilation error:

Error:(8, 27) value unary_+ is not a member of String
               val full = "" + first! + " " + last!

The same time, the following works:

val full = first! //+ " " + last!

What is going wrong in the fragment above?

Upvotes: 1

Views: 1970

Answers (3)

Alexey Romanov
Alexey Romanov

Reputation: 170745

I think if you follow the rules in Prefix, Infix, and Postfix Operations

"" + first! + " " + last!

gets parsed as

"".+(first).!(+ " ").+(last).!

and then it can't find the unary_+ required for + " ".

This transformation happens at the parsing stage, and so doesn't know anything about what methods are available.

Upvotes: 1

user unknown
user unknown

Reputation: 36229

With mkString it works:

import Helpers._

class Name(val first: String, val last: String) {
  val full = List (first!, last!).mkString (" ")
}

Upvotes: 1

Andrey Tyukin
Andrey Tyukin

Reputation: 44918

Postfix operators tend not to play well with binary infix operators. However, you might want to define ! as an unary operator that should be used in prefix position:

def unary_! : T = {
  assert(obj != null); obj
}

Then this here works:

val full = !first + " " + !last

But please be careful with this, probably nothing good will happen when you try to use it with boxed booleans or other types that support unary !. When in doubt, just use . or parentheses.


An aside about the usage of .!-syntax: when using sys.process, it's rather common to write cmd.! and cmd.!!, so keeping your definition and using .! wouldn't look "too weird".

Upvotes: 2

Related Questions