Scala a better println

2019-03-29 23:32发布

I often find myself doing things like:

println(foo)

when I'd like to do:

println foo

The compiler does not allow this.

Also, println is a mouthful, I really just want to say:

echo foo

So, in a base package object I created the echo version of println:

def echo(x: Any) = Console.println(x)

Easy enough, have echo application wide, great.

Now, how do I invoke echo without needing to wrap the Any to print in parens?

5条回答
劫难
2楼-- · 2019-03-29 23:59
object ∊ {def cho(s: Any) {println(s)}}

∊cho "Hello world"

will save your fingers.

It works because ∊ is a math-symbol in the Unicode Sm set, hence counts as an operator in Scala, so doesn't require spaces when placed next to alphanumeric characters.

You could also

object echo {def -(s: Any) {println(s)}}

echo-"Hello world"

which works pretty well IMO.

YEARS LATER EDIT: another almost-solution, using StringContext:

implicit class PimpMyString(sc: StringContext) {
  def echo(args: Any*) = println(sc.raw(args: _*))
}

echo"Hello World"
查看更多
forever°为你锁心
3楼-- · 2019-03-30 00:09

Scalaz has an enhanced Identity type that has a println method.

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> val foo = 1
foo: Int = 1

scala> foo println
1

If you don't want to depend on scalaz, you can create your own pimped identity and put an implicit for it in a package object.

查看更多
我命由我不由天
4楼-- · 2019-03-30 00:10

Define

trait ShortCuts {
  def echo(x: Any) = Console.println(x)
  def trace[T](x: T): T = { echo(x); x }
  // ...
}

object ↬ extends ShortCuts

and use happily without parentheses:

↬ echo "hello!"
查看更多
Luminary・发光体
5楼-- · 2019-03-30 00:15

What you're trying to achieve isn't possible in Scala.

The parentheses can only be dropped in so called point-free syntax, in which you must have a context object on the left side of the function so in your case you can only achieve the following, which kinda doesn't make any sense anyway:

Console println x

While I can see why you want to achieve this, probably considering simpler syntax constructs of other languages better, I would advice just to stick to the standard Scala way of doing things, so just use println(x) or consider other languages. Creating a delegating method for such a basic standard feature will definitely bring you only troubles in future managing of your projects - so definitely a "no-no" for the echo method.

There's an old saying for cases just like that: When in Rome, do as the Romans do.

查看更多
Explosion°爆炸
6楼-- · 2019-03-30 00:17

An interesting set of responses here, ranging from, it can't be done, to, it can be done, with this symbol-dependent hack, or with this dependency (Scalaz)

@Nikita correctly points out that one can just as easily add a snippet to their IDE (if that's how you roll) that does the println "legwork". While that is true, you generally have to stop typing to do ctrl-p-r, or whatever key combo you decide to use, which breaks your flow, IMO. So in the spirit of creating a "better" println, here's my take:

Create a base package object that your sub packages (model, view, dao, etc.) will inherit from (your own PreDef basically)

package com
package object company {

  // echo(foo)
  def echo(x: Any) = Console.println(x)

  // foo.echo   
  class AnyProvidesEcho(x: Any) { def echo = Console.println(x) }
  @inline implicit def any2Echo(x: Any) = new AnyProvidesEcho(x)
}

Usage:

val list = List(1,2,3)
val string = "c'est beacoup mieux mit butter"

list foreach echo
echo(string)
string.echo
查看更多
登录 后发表回答