问题
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?
回答1:
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"
回答2:
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!"
回答3:
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:
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.
回答5:
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
来源:https://stackoverflow.com/questions/10072476/scala-a-better-println