4

此线程相关

我仍然不清楚这两个定义之间的区别:

val foo = (arg: Type) => {...}
def(arg:Type) = {...}

据我了解:

1)val版本绑定一次,在编译时
创建单个Function1实例
可以作为方法参数传递

2) def 版本在每次调用
创建的每个调用新方法实例上重新绑定。

如果上述情况属实,那么在要执行的操作不依赖于运行时状态的情况下,为什么还要选择 def 版本呢?

例如,在 servlet 环境中,您可能想要获取连接客户端的 IP 地址;在这种情况下,您需要使用 def 作为,当然在编译时没有连接的客户端。

另一方面,您通常在编译时知道要执行的操作,并且可以使用不可变的val foo = (i: Type) => {...}

那么根据经验,应该只在存在运行时状态依赖时才使用 defs 吗?

感谢您的澄清

4

1 回答 1

4

我并不完全清楚你所说的运行时状态依赖是什么意思。vals 和s都def可以关闭它们的词法范围,因此以这种方式不受限制。那么Scala中的方法( defs)和函数(as s)有什么区别(之前已经问过并回答过val

你可以参数化一个def

例如:

object List {

  def empty[A]: List[A] = Nil     //type parameter alllowed here

  val Empty: List[Nothing] = Nil  //cannot create a type parameter
}

然后我可以打电话:

List.empty[Int]

但我将不得不使用:

List.Empty: List[Int]

但当然还有其他原因。如:

def 是 JVM 级别的方法

如果我要使用这段代码:

trades filter isEuropean

我可以选择声明isEuropean为:

val isEuropean = (_ : Trade).country.region = Europe

或者

def isEuropean(t: Trade) = t.country.region = Europe

后者避免在声明点而不是在使用点创建对象(用于函数实例)。Scala 正在为使用点的方法声明创建一个函数实例。如果我使用了_语法,那就更清楚了。

但是,在以下代码中:

val b = isEuropean(t)

...如果isEuropean被声明为 a def,则不会创建这样的对象,因此代码可能会更高效(如果在非常紧凑的循环中使用,其中每一纳秒都具有临界值)

于 2012-06-05T16:40:27.507 回答