代码之家  ›  专栏  ›  技术社区  ›  James Whiteley

不使用括号调用带参数的方法

  •  1
  • James Whiteley  · 技术社区  · 7 年前

    我用的是 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版本中似乎不起作用

    看起来很难看不是我要找的

    看起来基本上 隐式类 解决方案是这样的,我不需要任何外部依赖项。



    编辑

    This answer 已经被指出是一个潜在的解决方案,但是它没有解决我的问题,因为它依赖于 动态的 解决问题。如前所述, 动态的 有几个原因不能解决我的问题:

    • 它的行为很有趣

    如果您定义了一个val并尝试打印该val,它会返回val的名称,而不是它的值(正如@hypheri指出的那样):

    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 ,但在那之前,我会和它较量。

    2 回复  |  直到 7 年前
        1
  •  1
  •   metaphori    7 年前

    你无法实现

    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}
    

    我不喜欢@hseyin 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
    
        2
  •  3
  •   Hüseyin Zengin    7 年前

    唯一的方法是做一些和你想做的相似的事情 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

    推荐文章