2013-10-06 56 views
4

我知道,我应该使用()按照惯例,如果一个方法有副作用括号不纯函数

def method1(a: String): Unit = { 
    //..... 
} 

//or 

def method2(): Unit = { 
    //..... 
} 

我必须做同样的事情,如果一个方法没有副作用,但它不是纯粹的,没有任何参数,当然,每次调用它时都会返回不同的结果?

def method3() = getRemoteSessionId("login", "password") 
+4

我不知道“副作用”的确切定义,但非纯函数如何产生没有副作用的结果呢?如果一个函数使用随机数生成器或从任何I/O读取,我会认为这是一个副作用。 – ghik

+4

*在计算机科学中,如果函数或表达式除了返回值之外,还会修改某个状态**或与外部调用函数有可观察的交互,维基百科](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) –

+0

@ om-nom-nom,为什么不认为外部世界的功能可以是纯粹的? –

回答

1

编辑:在回顾了Luigi Plinge的评论后,我开始认为我应该重写答案。这也不是一个明确的是/否的答案,但一些建议。


第一:关于var的案例是一个有趣的案例。声明var foo会为您提供一个吸气器foo而不包括括号。显然这是一个不纯的调用,但它没有副作用(它不会改变调用者未观察到的任何内容)。第二,关于你的问题:我现在不会认为getRemoteSessionId的问题在于它是不纯的,但它实际上使得服务器为你保留一些会话登录,所以显然你会破坏性地干扰环境。然后method3()应该用括号书写,因为这种副作用性质。

第三个示例:获取目录的内容应写为file.children而不是file.children(),因为它又是一个不纯的函数,但不应该有副作用(除了对文件系统的只读访问以外) 。

第四个例子:鉴于上述情况,你应该写System.currentTimeMillis。我做往往写然而System.currentTimeMillis() ...

使用此规定的情况下,我试探性的答案是:括号是最好当函数有任何的副作用;或者如果它不纯并且取决于不在您的程序控制之下的状态。

有了这个定义,getRemoteSessionId是否已知副作用并不重要。另一方面,它意味着恢复写作file.children() ...

+0

回复:第二段:不是“有副作用”只是指由功能本身引起的副作用?例如,任何一种可变变量吸气剂都是不纯的,但不应该有副作用,所以我不同意“不纯净是与副作用同义的”。 –

+0

@LuigiPlinge我改写了答案。 –

1

Scala style guide建议:

方法充当任何形式的访问器(或者包封一个字段或一个逻辑特性)应不除非他们有副作用括号声明。

它没有提及除访问器以外的任何其他用例。因此,问题归结为您是否将此方法视为访问者,这取决于班级的其他成员如何设置,也许还取决于(预期的)呼叫站点。

+0

'def method3()= getRemoteSessionId(“login”,“password”)'不能成为访问者。 –

+0

@Alex:那么我会放在括号内。 –