构造函数的按名称参数

发布于 2024-08-29 05:02:54 字数 1145 浏览 10 评论 0原文

来自我的其他问题 有没有办法让构造函数按名称参数工作?我需要一种方法来提供一个在对象内按需/惰性/按名称执行的代码块,并且该代码块必须能够访问类方法,就好像代码块是类的一部分一样。

以下测试用例失败:

package test

class ByNameCons(code: => Unit) {

    def exec() = {
        println("pre-code")
        code
        println("post-code")
    }

    def meth() = println("method")

    def exec2(code2: => Unit) = {
        println("pre-code")
        code2
        println("post-code")
    }
}


object ByNameCons {

    def main(args: Array[String]): Unit = {
        val tst = new ByNameCons {
            println("foo")
            meth() // knows meth() as code is part of ByNameCons
        }
        tst.exec() // ByName fails (executed right as constructor)


        println("--------")


        tst.exec2 { // ByName works
            println("foo")
            //meth() // does not know meth() as code is NOT part of ByNameCons
        }       
    }
}

输出:

foo
method
pre-code
post-code
--------
pre-code
foo
post-code

coming from my other question is there a way to get by-name-parameters for constructors working? I need a way to provide a code-block which is executed on-demand/lazy/by-name inside an object and this code-block must be able to access the class-methods as if the code-block were part of the class.

Following Testcase fails:

package test

class ByNameCons(code: => Unit) {

    def exec() = {
        println("pre-code")
        code
        println("post-code")
    }

    def meth() = println("method")

    def exec2(code2: => Unit) = {
        println("pre-code")
        code2
        println("post-code")
    }
}


object ByNameCons {

    def main(args: Array[String]): Unit = {
        val tst = new ByNameCons {
            println("foo")
            meth() // knows meth() as code is part of ByNameCons
        }
        tst.exec() // ByName fails (executed right as constructor)


        println("--------")


        tst.exec2 { // ByName works
            println("foo")
            //meth() // does not know meth() as code is NOT part of ByNameCons
        }       
    }
}

Output:

foo
method
pre-code
post-code
--------
pre-code
foo
post-code

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

早乙女 2024-09-05 05:02:55

这是因为当您创建这样的实例时:

val tst = new ByNameCons {
  ...
}

.. 您实际上是在创建一个匿名类,就像在 java 中一样。
上面的代码与:

val tst = new ByNameCons() { ... }

.. 相同,而按名称传递的正确语法是:

val tst = new ByNameCons( { ... } )

对于构造函数,不能像函数那样省略括号。

This is because when you're making an instance like this:

val tst = new ByNameCons {
  ...
}

.. you're actually creating an anonymous class, like in java.
The above code is the same as:

val tst = new ByNameCons() { ... }

.. while the correct syntax for passing by-name is:

val tst = new ByNameCons( { ... } )

You cant omit parentheses the same way for constructors as with functions.

静谧幽蓝 2024-09-05 05:02:55
val tst = new ByNameCons( {
   println("foo")  
} )

认为这样做可能更容易:

object ByNameCons {
  def apply(code: => Unit) = new ByNameCons(code)
}

val tst = ByNameCons { // no "new" here -- can't mix traits either
  println("foo")
}
val tst = new ByNameCons( {
   println("foo")  
} )

Thought it is probably just easier to do this:

object ByNameCons {
  def apply(code: => Unit) = new ByNameCons(code)
}

val tst = ByNameCons { // no "new" here -- can't mix traits either
  println("foo")
}
无法言说的痛 2024-09-05 05:02:55

我不知道为什么,但似乎在创建类时使用 {} 或 () 会改变行为。使用以下类,

class Coder(code: => Unit) {
  def exec = { 
    println("before")
    code
    println("after")}
  }
}

scala> val brackets = new Coder {println("testing")}
testing
brackets: Coder = $anon$1@1af7a03
scala> brackets exec
before
after

现在可以根据

scala> val parens = new Coder(println("testing"))
parens: Coder = Coder@dca3ed
scala> parens exec
before
testing
after

需要以另一种方式定义。似乎在第一个表示法中,编译器将括号解释为要计算为 Unit 的块,而不是调用时计算为 Unit 的匿名函数>。

FWIW,使用 ({ ... }) 也可以正常工作。

I dont know why, but it appears that using {} or () when creating the class changes the behavior. Using the following class,

class Coder(code: => Unit) {
  def exec = { 
    println("before")
    code
    println("after")}
  }
}

scala> val brackets = new Coder {println("testing")}
testing
brackets: Coder = $anon$1@1af7a03
scala> brackets exec
before
after

Now instead if defined another way,

scala> val parens = new Coder(println("testing"))
parens: Coder = Coder@dca3ed
scala> parens exec
before
testing
after

as desired. It seems as if in the first notation, the compiler is interpreting the brackets as a block to be evaluated to Unit, instead of an anonymous function which, when called, evaluates to Unit.

FWIW, using ({ ... }) also works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文