Scala应用方法调用作为括号与隐式参数冲突

时间:2018-05-09 18:08:31

标签: scala apply implicit-parameters

Cay Horstmann的书" Scala for the Impatient"关于申请方法:

  

有时,()表示法与另一个Scala功能冲突:   隐含参数。例如,表达式"Bonjour".sorted(3)   产生错误,因为可以选择调用已排序的方法   有序,但3不是有效的订购。

解决方案是将"Bonjour".sorted分配给变量并在其上调用apply,例如:

val result = "Bonjour".sorted
result(3)

或明确致电申请:

"Bonjour".sorted.apply(3)

但为什么这不起作用并产生编译错误:

("Bonjour".sorted)(3)

sorted方法返回String,它可以被显式转换为StringOps,并且括号用于包装字符串表达式。 为什么编译器不接受调用StringOps

的apply方法

1 个答案:

答案 0 :(得分:2)

您可以使用if (atty=== '0'){ // atty.trim() === '0' 查看早期丢弃的parens:

function myfunc(){
  var atty = document.getElementById("attorney").innerText;
  if (atty.trim() === '0') {
    document.getElementById("profiletab1").style.display = "none";
  }
}

额外的parens什么都不做。编译器只看到一个应用程序-Xprint:parser。因为它是一个应用程序,所以不会进行“隐式应用程序”转换。

在任何情况下,方法scala> implicit class x(val s: String) { def scaled(implicit i: Int) = s * i } defined class x scala> "hi".scaled(5) res0: String = hihihihihi scala> { implicit val n: Int = 5 ; "hi".scaled } res1: String = hihihihihi scala> "hi".scaled(5)(3) res2: Char = i scala> { implicit val n: Int = 5 ; ("hi".scaled)(3) } res3: String = hihihi scala> :se -Xprint:parser scala> { implicit val n: Int = 5 ; ("hi".scaled)(3) } [[syntax trees at end of parser]] // <console> package $line8 { object $read extends scala.AnyRef { def <init>() = { super.<init>(); () }; object $iw extends scala.AnyRef { def <init>() = { super.<init>(); () }; import $line3.$read.$iw.$iw.x; object $iw extends scala.AnyRef { def <init>() = { super.<init>(); () }; val res4 = { implicit val n: Int = 5; "hi".scaled(3) } } } } } res4: String = hihihi scala> 的含义取决于预期的类型。

我们期望额外的parens有所作为的原因是parens覆盖运算符的优先级。但expr(args)只是scaled

可能这个规格实际上很清楚:

(x)要求x适用于e(args)。特别是,args根据e的参数类型进行了类型检查。

如果args是值,则

e将被视为e(args),但e.apply(args)是一种方法。

您希望“隐式应用程序”插入隐式args,但这仅适用于尚未应用e的情况。或者scaled可以被视为e,即(e)(args)

当写为(e(_))(args)时,(x => e(x))(arg)不是e.apply(arg)之类的应用,因此您可以从隐式应用等转化中受益。