问题首先:箭头反模式是否是在Scala中做事的方式?
我已经从Java过渡到Scala大约3个月了。我开始看到反箭头模式在Scala中作为一个标准。
例如,在Java中,我希望尽快从方法中返回。我们不喜欢很多内心的嵌套。如果你有很多它们被称为箭头反模式。您可以在此处阅读:http://c2.com/cgi/wiki?ArrowAntiPattern
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
}
如果我在Scala中写这个,我必须使用匹配案例语句,这会导致很多缩进。请记住,这只是一个虚拟示例,我尝试仅传达Scala的嵌套和缩进。
def isValid(input:String): Boolean = {
(input.trim.length < 1) match {
case true =>
input.substring(0,3) match {
case sthCase if(sthCase=="sth") =>
//do some more checks etc
//eventually arrive at the "true" branch
... case valid => true
case sthElse if (sthCase=="bla") => //some more code etc
case _ => false
}
case _ => false
}
}
我知道这个例子可能与我编写Java的方式相同,但如果不是返回true或false,我想将该值赋给变量ie:val valid = (input.trim.length < 1) match ...
那么这是唯一的方法这样做,因为你无法重新分配给val。我可以使用var
代替val
,但之后我会使用Java而不是Scala。
问题,重复:
所以问题是,箭头反模式是在Scala中做事的方式还是我错过了什么?有没有更好的方法在Scala中做我刚写的内容(请记住,我希望将匹配语句结果分配给val
变量)。
答案 0 :(得分:4)
请注意,只要代码的所有部分都是单入口/单出口,您就可以始终在Scala中使用分解。这是有效的,因为Scala中的嵌套函数可以访问外部函数的局部变量。 E.g:
def isValid(input: String): Boolean = {
def testLength = input.trim.length >= 1
def testSomething = input.substring(0, 3) == "sth"
return testLength && testSomething
}
因此,您可以根据需要将任何类似箭头的结构分解为其子组件。
另请注意,使用匹配来测试布尔值或比较某些内容是否过分是显而易见的。
答案 1 :(得分:3)
您可以轻松地将您的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
}
if/else
就像scala中的所有内容都是一个表达式并且有一个返回值,所以你不妨将它用于一个赋值:
val isValid =
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"))
答案 2 :(得分:3)
如果函数中return
太多,则缺少函数:
def isValid(s: String): Boolean = {
def isLengthValid = s.trim().length() > 0
def shouldNotContainsSomething = s.substring(0, 3) != "sth"
isLengthValid && shouldNotContainsSomething
}
答案 3 :(得分:2)
不要做货物崇拜just because some rule says so。 Scala的好处是你可以从两个世界中做到最好 - 例如有时用可变风格写的算法比不可变的风格要清晰得多。
顺便说一下,还有require
方法,它通常用于验证失败(但它会出现异常)。