Scala 为什么可以';类val参数不能按名称调用吗?
我正试图使用一个类作为一个接口聚合一组API函数的代理。其中有几个是空函数,但我不希望在类构造函数中包含它们来触发API调用。我现在的解决方案是将调用包装在一个文本空函数Scala 为什么可以';类val参数不能按名称调用吗?,scala,Scala,我正试图使用一个类作为一个接口聚合一组API函数的代理。其中有几个是空函数,但我不希望在类构造函数中包含它们来触发API调用。我现在的解决方案是将调用包装在一个文本空函数newmyclass(()=>apiCall)中,然后显式调用成员函数。这并不是那么糟糕,但我想知道是否有一个技术原因,我不能仅仅使用callbyname参数来传递对该方法的惰性引用 例如: scala> class MyClass(val apiCall: => String) <console>:1:
newmyclass(()=>apiCall)
中,然后显式调用成员函数。这并不是那么糟糕,但我想知道是否有一个技术原因,我不能仅仅使用callbyname参数来传递对该方法的惰性引用
例如:
scala> class MyClass(val apiCall: => String)
<console>:1: error: `val' parameters may not be call-by-name
class MyClass(val apiCall: => String)
scala>classmyclass(val-apiCall:=>String)
:1:错误:`val'参数不能按名称调用
类MyClass(val apiCall:=>字符串)
Edit我应该指定我的问题是为什么类不能有
val
参数。添加了一个示例。一个类很可能有按名称调用的参数,只要它们不是val
或var
:
> scala
Welcome to Scala version 2.11.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_55).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class Foo(f: => Unit) {
| def run(): Unit = f
| }
defined class Foo
scala> new Foo(println("hello"))
res0: Foo = Foo@5da6b8c6
scala> res0.run()
hello
val
或var
参数不能按名称显示的原因很简单,就是类字段不能按名称显示,只能按局部变量显示。因此,以下内容无效:
scala> class FooInvalid(val v: => Unit) {
<console>:1: error: `val' parameters may not be call-by-name
class FooInvalid(val v: => Unit) {
^
最后,不必将v
定义为()=>单元类型的val
,您可以将其定义为单元类型的def
。然后你得到了一开始你可能想要的行为:
scala> class FooDef(v0: => Unit) {
| def v: Unit = v0
| }
defined class FooDef
scala> new FooDef(println("hello"))
res5: FooDef = FooDef@2e04a041
scala> res5.v
hello
有人可能会争辩说编译器应该自己进行这种转换,但这与val
必须是稳定的语义不一致(例如,使用稳定的值,您可以导入x.。
其成员,您不能使用不稳定的值),因为def
(即使没有()
)是一个不稳定的值。最好将这个小的重写留给用户,而不是引入一个非常奇怪的错误。但如果它们是val
s,就不要这样,这是我的问题。对不起,应该更具体一点。回答得很好。关于与局部变量的比较,局部变量不能按名称命名,但可以是惰性的。编译器对此也抱怨不已,建议使用按名称参数,这是因为惰性参数通常不存在。在某个时候,它们被考虑包含在Scala中,但结果证明它们的实现比合理的要困难得多,所以被放弃了。
scala> class FooDef(v0: => Unit) {
| def v: Unit = v0
| }
defined class FooDef
scala> new FooDef(println("hello"))
res5: FooDef = FooDef@2e04a041
scala> res5.v
hello