我正在使用以下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
Dynamic
[see here] 似乎不适用于我的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>
答案 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.dynamics
和scala.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