2016-05-22 34 views
1

在Python我可以这样做:功能分配到值/变量斯卡拉

In [24]: def m1(): 
    ....:  return "I am legend" 
    ....: 

In [25]: f1 = m1 

In [26]: type(f1) 
Out[26]: function 

In [27]: type(m1) 
Out[27]: function 

而在Scala中,

def m1() = "I am legend" 

的就是我上面做的相当的不

val f1 = m1 

但我反而必须指定

scala> val f1:()=> String = m1 
f1:() => String = <function0> 

scala> val f1 = m1 _ 
f1:() => String = <function0> 

为什么这个设计选择做? 正如有人来斯卡拉从Python中,能够通过

val f1 = m1 

分配的功能似乎比不必做上述方法中的一个更自然。

我知道val f1 = m1

结果m1被调用,并将所得值分配给f1但不会是一直更加清晰遵循了Python方法 ,需要在这种情况下,括号,而不是即

val f1 = m1() 

在我希望调用函数并将结果分配给f1的情况下?

+3

这是一个设计选择。允许arity-0的方法省略括号意味着'val f1 = m1'不能既是方法调用又是函数分配。像大多数事情一样,这是一种折衷。设计人员虽然省略括号会更有用,因为它会比将函数分配给方法更多。 –

回答

2

在Scala中,如果方法没有副作用,可以大大提高可读性,则应该省略括号。从Scala docs引用:

Scala的允许括号对元数-0的方法(无 参数)遗漏。但是,只有当方法 没有副作用(纯功能)时才应使用此语法。换句话说, 在调用queue.size, 时忽略括号是可以接受的,但在调用println()时不会。这个约定反映了上面给出的方法 声明约定。

宗教上遵守这一惯例将大大改善代码 的可读性,并将使它更容易理解一目了然的任何给定方法的最基本的操作。抵制省略 括号的冲动只是为了保存两个字符!

有一些更深层次的考虑,在这个关于统一访问 原则。他们在Martin Odersky等人的“Programming in Scala”一书中的10.3节中阐述。我不会在这里引用它(它超过两页长),但重点是在调用arity-0方法时忽略括号可以让您无缝地将这些方法更改为vals,甚至无需触摸客户端的代码。这样做,您可以管理通常的时间和空间折衷。特别是,你可以override defs with vals(但不是反之亦然):

abstract class Mass { 
    def kilograms: Double 
} 

class Grams(grams: Double) extends Mass { 
    val kilograms: Double = { 
    Thread.sleep(5000) // pretend to think hard 
    grams/1000.0 
    } 
} 

More on def vs val vs lazy val

当然,这一切的东西就不会如蟒蛇般的分配被允许成为可能。