3

Scala 的“call be name”示例:

def giveMeName(b: => String)

Java结果:

public class some.package.CallByNameEx {
    public void giveMeName(scala.Function0<java.lang.String>);
    public some.package.CallByNameEx();
}

Java 的功能接口 API 示例:

void giveMeName(Supplier<String> b)

Java结果:

public class some.package.SupplyEx {
    public some.package.SupplyEx();
    void giveMeName(java.util.function.Supplier<java.lang.String>);
}

javap考虑到上述两种情况的结果几乎相同,它们在内部评估的方式是否有任何重大差异

根据我目前的理解,它们都使用闭包并懒惰地评估表达式。如果理解有误请指正。

4

2 回答 2

2

你说得对,call-by-name语法几乎是一种速记,可以让你避免处理传递的额外官僚主义Function0


在内部,b: => String将由Function0-代表b: () => String

不同之处在于,通过使用call-by-name,您可以简单地忽略 using 的实现细节Function0

让我们看看它会是什么样子b: () => String

def giveMeName(b: () => String): String = b.apply()

并再次使用call-by-name

def giveMeName(b: => String): String = b

请注意如何apply()避免样板调用。

所以,它是一种语法糖,但不是针对 Java 的函数式接口,而是针对 Scala 的本机Function0

我在这里写了更多关于此的内容:http: //4comprehension.com/leveraging-lambda-expressions-for-lazy-evaluation-in-java/

于 2018-07-23T14:41:14.697 回答
1

它可以被认为是语法糖吗?是的,可以说。Java8的功能接口API?不。

让我们按照http://wiki.c2.com/?SyntacticSugar中的定义:

添加到语言或其他形式主义中以使其对人类更甜美的特征,但不影响形式主义的表现力(比较 chrome)。用过,特别是。当糖特征明显而微不足道地翻译成符号中已经存在的其他结构时。

所以 Scala 特性只能是其他 Scala 特性的语法糖,而不是 Java 特性的语法糖。在这种情况下,def giveMeName(b: => String)被翻译成类似的东西def giveMeName(b: () => String)。“可以说”的部分是翻译声明是不够的:您还需要翻译所有调用,并且该方法已标记,因此您不能将某些类型传递() => Stringdef giveMeName(b: => String).

考虑到上述两种情况的 javap 结果几乎相同,它们在内部评估的方式是否有任何重大差异

在结果中,您显示没有要评估的内容,如果您替换Supplier<String>为,它们仍然“几乎相同” List<String>。这是否意味着按名称调用是语法糖List?当然不是。

但是 Scala() => String语义上等价于Supplier<String>(这不是你可以从 javap 中看到的),并且因为=> String等价于() => String

他们都使用闭包并懒惰地评估表达式

如果“它们”是您展示的 API,则不,它们本身也不使用闭包。您可以将闭包传递给两者(或非闭包)。

于 2018-07-23T16:56:00.143 回答