将具有 N 个参数的 def 实现为 FunctionN 类型的 val
我可以使用 val
实现 def
,其中 def
不带任何参数:
trait T { def foo: Int }
class C(val foo: Int) extends T
为什么不能将其扩展为实现 def< /code> 将 N 个参数传入一个
FunctionN
的 val?我希望能够实现类似的东西:
def expensiveOperation(p: Int => Boolean) : List[Int]
使用惰性函数val
。比如:
val expensiveOperation = {
val l = //get expensive list
l.filter _ //partially applied function
}
我知道这个语法似乎不适用于 2.8。我是否遗漏了什么,为什么我不能实现将参数作为函数val
的def
?
I can implement a def
with a val
where the def
takes no arguments:
trait T { def foo: Int }
class C(val foo: Int) extends T
Why can this not be extended to implementing a def
taking N args to a val which is a FunctionN
? I want it possible to implement something like:
def expensiveOperation(p: Int => Boolean) : List[Int]
With a lazy function val
. Something like:
val expensiveOperation = {
val l = //get expensive list
l.filter _ //partially applied function
}
I know that this syntax does not seem to work on 2.8. Is there something I'm missing, why can I not implement a def
taking parameters as a functional val
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
现在,后期编辑,我想我明白你在追求什么。但你不能做你想做的事,因为类型签名不匹配。
在这两种情况下,您什么都不提供并返回一个 Int(在本例中为 5)。伟大的!
现在你提供一些东西。但 val 只是某个地方存储的对象。您可以向标签引用的对象提供一些内容,但这与向标签“x”提供一些内容不同。
如果您希望 val 覆盖它,则需要使用以下 def:
现在,您可以不带参数调用某些内容,并且它返回可以采用 Int=>Boolean 函数并返回 List[Int] 的内容。这正是您通过 val 得到的结果——在这两种情况下,您都拥有返回具有您想要的功能的对象的名称。
(在 Scala 中,val 实际上是作为带有 getter 方法的隐藏字段实现的,这些方法不带参数并返回隐藏字段中的任何内容。所以它确实是一个与 def 一样的方法。)
Now, post-edits, I think I understand what you're after. But you can't do what you want because the type signatures don't match.
In both cases you supply nothing and get back an Int (in this case 5). Great!
Now you supply something. But a val is just a stored object somewhere. You can supply something to the object that the label refers to, but that's not the same as supplying something to the label 'x'.
Here's the def you need to use if you want a val to override it:
Now you have something that you call with no parameters and it returns something that can take a Int=>Boolean function and give you a List[Int] in return. That's exactly what you get with the val--in both cases, you have the name of something that returns an object that has the functionality you want.
(In Scala, vals are actually implemented as hidden fields with getter methods that take no parameters and return whatever's in the hidden field. So it really is a method just like the def is.)
val
不接受参数,因为它是计算并存储在字段中的。但我可能只是建议您参考我过去两天在邮件列表上发表的大量帖子。或者更确切地说,让我们从 Java 的角度来考虑,因为 Scala 在 jvm 层面与 Java 兼容,并且它肯定必须遵守 jvm 规则。让我们从第一个类开始:
现在,让我们扩展它:
因此,从 Java 中,我们知道类
X
具有方法expenseOperation
,该方法接收Function1[Int , Boolean]
并返回List[Int]
。现在我们进入
Y
类。当然,它必须定义相同的方法,但它还必须定义 getterexppressiveOperation
,它不接收参数并返回Function1[Function1[Int, Boolean],List[Int]]
。只要
X
中不存在此附加方法,它就可能是可行的。那么让我们来定义它:如何定义它? Scala 是否将
apply
的主体复制为exppressiveOperation
的主体(接收参数的主体,而不是 getter 的主体)?它可能仍然可行。不过,让我们尝试其他方法:现在,我们如何重写参数接收
extenseOperation
?我想我们可以这样写:这是可行的。但我个人认为这有点复杂。我的建议:写一个简短的 SID,并在 Scala 邮件列表上达成一些协议。不过,如果没有代码来实现它,我认为它被采用的机会不大——Scala 必须跟踪每个函数类型的
val
来确定它是否覆盖了def< /code> 或不。
A
val
doesn't take arguments, because it is computed and stored in a field. But I might just refer you to the extensive posts I did the last two days on the mailing lists.Or, rather, let's consider it from a Java point of view, since Scala is compatible with Java at the jvm level, and it surely must obey jvm rules. Let's start with the first class:
Now, let's extend it:
So, from Java, we know that class
X
has the methodexpensiveOperation
, which receivesFunction1[Int, Boolean]
and returnsList[Int]
.Now we go to class
Y
. Naturally, it has to define the same method, but it also has to define the getterexpensiveOperation
, which receives no arguments and returnsFunction1[Function1[Int, Boolean],List[Int]]
.It might be workable, as long as this additional method didn't exist in
X
too. So let's define it:How does that get defined? Does Scala copy
apply
's body as a body forexpensiveOperation
(the one receiving a parameter, not the getter one)? It might still be workable. Let's try something else, though:Now, how do we override the parameter-receiving
extensiveOperation
? I suppose we could write it like this:That's workable. But I, personally, think it is a bit convoluted. My suggestion: write up a short SID, and get some agreement on a Scala mailing list. Without code to implement it, though, I don't think it has much chance of being adopted -- Scala has to track every function-typed
val
to figure if it is overriding adef
or not.您始终可以将其转发给您的 val:
并且,尽管这不能回答您的问题,但看起来除非您的
// ... get昂贵列表
代码取决于谓词p
,那么你可以做类似的事情:You could always just forward it to your val:
And, although this doesn't answer your question, It looks like unless your
// ... get expensive list
code depends on the predicatep
, then you could just do something similar to:编辑:好吧,我没明白你的意思。但是,如果您的意思是我的想法...
您可以使用缩写语法创建一个应用操作的 val:
但这实际上并没有缓存列表,这正是我认为您想要的。原因是这种简写语法将所有内容放在=>之后。进入Function1的apply方法。您可能希望像这样存储列表:
据我所知,对此没有很好的速记。
编辑:如果您很乐意在该块之外创建列表,那么有一个简写(另请参阅评论):
Edit: okay, I didn't figure out what you actually meant. But if you had meant what I thought...
You can, using abbreviated syntax, create a val that applies an operation:
But this doesn't actually cache the list, which is what I think you want. The reason is that this short-hand syntax puts everything after => into the apply method of Function1. You probably want the list to be stored like so:
and for that there isn't a great shorthand that I know of.
Edit: If you're happy to create the list outside of that block, then there is a shorthand (see comment also):