我目前正在研究几个scala代码库(每个代码库由不同地理位置的不同人员维护),我觉得Scala提供了不同的方法来做同样的事情。我的第一手理解是Scala有一层相当厚的语法糖代码,所以我现在的目标是渗透到那层,看看什么是基本的构建块。
正如我在阅读一些文档后所理解的那样,scala中的每个函数定义基本上都是一个带有填充“apply”方法的特征。(类似于java中匿名body / class的接口)。将此设置为基础(如果我的基础理解本身是错误的,请纠正我),我正在使用Scala中的函数定义。
考虑一下:
def func (s:String):Int = {
100
}
评估为
new Function1[String, Int] {
def apply(s:String):Int = {
100
}
}
但是,以下评估特征定义的内容是什么(以及如何)?
def func (body: => Boolean):Int = {
body;
100;
}
在这种情况下,“新功能......”代码是什么样的?
答案 0 :(得分:3)
如果出现混淆,请查看package.json
输出。 Scala的REPL提供了方便的检查方法:
"scripts": {
"build": "npm run lint && npm run release",
"lint": "./node_modules/.bin/eslint ./src/**/*.js",
"dev": "node server.js",
"release": "NODE_ENV=production webpack --config ./webpack.dist.js --progress",
"test": "./test/*.test.js --compilers js:babel-core/register --recursive --reporter spec"
},
所以在这里你可以看到javap
在字节码中表示为scala> def func (body: => Boolean):Int = {
| body;
| 100;
| }
func: (body: => Boolean)Int
scala> :javap -c func
Compiled from "<console>"
public class {
public static final MODULE$;
public static {};
Code:
0: new #2 // class
3: invokespecial #12 // Method "<init>":()V
6: return
public int func(scala.Function0<java.lang.Object>);
Code:
0: aload_1
1: invokeinterface #20, 1 // InterfaceMethod scala/Function0.apply$mcZ$sp:()Z
6: pop
7: bipush 100
9: ireturn
public ();
Code:
0: aload_0
1: invokespecial #24 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #26 // Field MODULE$:L;
8: return
}
。
我在这里使用body: => Boolean
版本。 scala.Function0<java.lang.Object>
将尝试尽可能多地重用java8的功能,如默认方法(在接口中)或SAM(您可以尝试scala 2.11.8
标志,为Scala 2.12
启用introp。这将导致另一个字节码(与java&lt; 8不兼容)和更好的性能。您可以详细了解-Xexperimental
更改here。
答案 1 :(得分:1)
首先
def func (s:String):Int = {
100
}
不是一种功能,它是一种方法,它没有任何价值,并且不会自己评估任何东西。当放置在功能上下文中时,它会扩展为一个函数,但是扩展为另一个函数(Scala创建一个包装器):
new Function1[String, Int] {
def apply(s:String):Int = {
func(s)
}
}
所以,如果你想进行eta-expand(Scala将术语转换为函数的术语)
def func (body: => Boolean):Int = {
body;
100;
}
应该是这样的:
new Function1[=> Boolean, Int] {
def apply(body: => Boolean):Int = {
func(body)
}
}
和Scala将类型显示为:
(=> Boolean) => Int
但问题在于,名称类型不能用作类型参数,因此看起来没有合法的方法来使用Function1
特征定义此函数。
<强>更新强>
看起来有一种使用lambda语法的解决方法(我不能明确地声明body
的类型,但不允许使用by-name):
var expandedFunc: (=> Boolean) => Int = body => func(body)
答案 2 :(得分:0)
在Dviem的评论的帮助下,代码看起来应该是这样的:
.attr("d",function(d) {return lineFunction(d.borders);})