使用参数调用方法而不使用括号

时间:2018-06-13 13:55:27

标签: scala

我正在使用以下implicit class来调用一个函数,否则该参数不需要在括号中写入参数就可以获取参数:

scala> implicit class Print(string: String) {
     |   def echo: Unit = Console.println(string)
     | }
defined class Print

scala> "Hello world" echo
Hello world

然而,虽然这有效,但我真的不喜欢它的外观,我的目标是在输入变量前面调用方法,因为我觉得它看起来更好。

有没有简单的方法,在不依赖外部库的情况下,能够在提供参数之前调用方法而不需要括号?隐式类是我到目前为止所使用的,但不一定是最终的解决方案。

我想输入的是"Hello world" echo

scala> echo "Hello world"


我尝试过的替代方案:

  • 使用apply方法的对象

需要括号

object echo {
  def apply(string: String): Unit = Console.println(string)
}

echo "Hello world" // Error: ';' or newline expected

似乎不适用于我的Scala版本

看起来丑陋而不是我想要的

基本上看起来我的implicit class解决方案做了什么,我不想要任何外部依赖。


修改

This answer一直被认为是一种潜在的解决方案,但它并没有解决我的问题,因为它依赖于Dynamic来实现解决方案。如前所述,由于以下几个原因,Dynamic无法解决我的问题:

  • 表现得很有趣

如果你定义一个val并尝试打印那个val,它会返回val的名字而不是它的值(正如@metaphori所指出的那样):

object println extends Dynamic {
  def typed[T] = asInstanceOf[T]
  def selectDynamic(name: String) = Console.println(name)
}

val x = "hello"
println x     // prints: x
  • 当我尝试重新创建时,链接到的具体示例无效 - 它仍然显示';' or newline expected错误

如果我误解了如何实现它,那么我会感谢一个scalafiddle,证明这个解决方案解决了我的问题,并乐意承认这个问题是the previously mentioned answer的重复,但在那之前我确实对它提出质疑。 / p>

2 个答案:

答案 0 :(得分:3)

AFAIK唯一可以做类似于你想要的事情的方法就是像这样扩展Dynamic

object println extends Dynamic {
  def typed[T] = asInstanceOf[T]
  def selectDynamic(name: String) = Console.println(name)
}

并将其用于:

println `Hello World`

编辑:当然您需要通过添加编译器参数-language:postfixOps-language:dynamics或导入scala.language.dynamicsscala.language.postfixOps

来启用相关功能

答案 1 :(得分:1)

你无法实现

echo "str"

因为Scala不是例如Ruby:它在语法上要求函数调用使用括号。 这不是语义问题,也不是如何实现或使用什么技术:这是抱怨的解析器。 关键是x y实际上被解释为x.y,这意味着y必须是一种方法。

请参阅Scala Language Specification, section 6.6 Function Applications

SimpleExpr    ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs ::=  ‘(’ [Exprs] ‘)’
                |  ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
                |  [nl] BlockExpr
Exprs         ::=  Expr {‘,’ Expr}

我不喜欢@hüseyin-zengin的技巧,因为它利用了动态方法调用,并且也没有按预期工作:

val x = "hello"
println x     // prints: x

要部分达到您喜欢的效果,您需要使用中缀运算符表示法

object run { def echo(s: String) = println(s) }

run echo "hello" // OK
run.echo "hello" // error: ';' expected but string literal found.

您也可以使用符号来减少“打字”开销(虽然可能会被感觉怪异):

object > { def echo(s: String) = println(s) }

> echo "hello" // OK