箭头反模式是Scala中的标准吗

箭头反模式是Scala中的标准吗,scala,coding-style,nested,standards,anti-patterns,Scala,Coding Style,Nested,Standards,Anti Patterns,第一个问题:箭头反模式是Scala中的工作方式吗 我已经从Java过渡到Scala大约3个月了。我开始将反箭头模式视为Scala中的一个标准 例如,在Java中,我喜欢尽快从方法返回。我们不喜欢很多内部嵌套。如果你有很多,这就是所谓的箭头反模式。您可以在此处阅读: Java示例: boolean isValid(String input){ if (input.trim().length() <1) return false //return early if (input.sub

第一个问题:箭头反模式是Scala中的工作方式吗

我已经从Java过渡到Scala大约3个月了。我开始将反箭头模式视为Scala中的一个标准

例如,在Java中,我喜欢尽快从方法返回。我们不喜欢很多内部嵌套。如果你有很多,这就是所谓的箭头反模式。您可以在此处阅读:

Java示例:

boolean isValid(String input){
  if (input.trim().length() <1) return false //return early
  if (input.substring(0,3).equals("sth")) return false;

  //do some more checks for validity then return true

  return true
}
布尔值有效(字符串输入){

if(input.trim().length()您的java示例可以轻松地在scala中转换为
if/else
,而无需显式返回,也无需任何额外的嵌套级别

def isValid(input: String) = {
  if (input.trim().length() <1) false
  else if (input.substring(0,3).equals("sth")) false
  else true
}
或者在这种情况下,您也可以简单地编写

val isValid = (input.trim().length() >= 1) && (!input.substring(0,3).equals("sth"))
不要做货物崇拜。Scala的好处是,你可以从两个方面都做到最好——例如,有时用可变风格编写的算法比不变风格编写的算法更清晰


顺便说一句,还有
require
方法,通常用于验证失败(但它会出现异常).

请注意,只要代码的所有部分都是单入口/单出口的,您就可以在Scala中始终使用分解。这是因为Scala中的嵌套函数可以访问外部函数的局部变量。例如:

def isValid(input: String): Boolean = {
  def testLength = input.trim.length >= 1
  def testSomething = input.substring(0, 3) == "sth"

  return testLength && testSomething
}
因此,您可以根据需要将任何箭头式结构分解为其子组件


还请注意,使用match测试布尔值或比较某个值是否相等是一种过分的做法。

如果函数中返回的
太多,则函数将丢失:

def isValid(s: String): Boolean = {
  def isLengthValid = s.trim().length() > 0
  def shouldNotContainsSomething = s.substring(0, 3) != "sth"

  isLengthValid && shouldNotContainsSomething
}

我明白你的意思。我应该用一个非布尔的例子来说明我的观点。这也不是一个真正的新技术。看。这可能是Pascal语言家族中所有语言都有嵌套过程/函数的一个主要原因。确实如此,但这只是一个开始。我可能会在另一篇文章中继续这个问题,但有点重复eper/比嵌套的几个布尔值更高级。再次感谢
return
关键字可以而且应该作为一种风格首选项省略,我喜欢在长函数末尾显式显示
return
。这不仅可以更方便地直观地查找函数结尾(假设您有语法高亮显示),它还清楚地表明,我们处理的是一个函数而不是一个过程,而不必检查函数签名。两种方法的语义都是相同的,因此这两种方法在客观上都不是更好的。如果省略
return
,则会使源代码“grep-able”对于
return
s,它可以被其他内容替换。无需在Scala中使用
equals
进行字符串比较。
=
操作符自动使用
equals
方法。它是从Java示例复制的-我只是添加了
==false
来保留该条件。因此它应该是de>!=
。我已经更新了它。
def isValid(input: String): Boolean = {
  def testLength = input.trim.length >= 1
  def testSomething = input.substring(0, 3) == "sth"

  return testLength && testSomething
}
def isValid(s: String): Boolean = {
  def isLengthValid = s.trim().length() > 0
  def shouldNotContainsSomething = s.substring(0, 3) != "sth"

  isLengthValid && shouldNotContainsSomething
}