如何用惯用的Scala编码?
假设我想编写一个函数如何用惯用的Scala编码?,scala,Scala,假设我想编写一个函数defpair(s:String):Option[(String,String)]来将字符串转换为Scala中的键值对。字符串应类似于:“ 您将如何更正下面的解决方案 def pair(s:String) = { val a = s.split(":"); if (a.length == 2) Some((a(0).trim, a(1).trim)) else None } def对(s:字符串)={ val a=s.split(“:”);如果(a.length==2)一
defpair(s:String):Option[(String,String)]
来将字符串转换为Scala中的键值对。字符串应类似于:“
您将如何更正下面的解决方案
def pair(s:String) = {
val a = s.split(":"); if (a.length == 2) Some((a(0).trim, a(1).trim)) else None
}
def对(s:字符串)={
val a=s.split(“:”);如果(a.length==2)一些((a(0.trim,a(1.trim))其他无
}
我要去掉分号,把它改成两行。否则,这是一个非常好的函数代码 再看一眼,模式匹配似乎更合适:
def pair(s:String) =
s.split(":") match {
case Array(a, b) => Some((a, b))
case _ => None
}
在这种情况下,模式匹配更适合的原因是您使用if-else
来模拟数据结构解构,这正是模式匹配的目的。这将使您的抽象级别降低,逻辑更加复杂,并有更多机会植入bug。同样,您的实现依赖于a(0)
中的部分函数,这是一种不鼓励的做法
部分函数是一种未为其输入的整个域定义的函数。在您的情况下,这意味着对空数组调用a(0)
将导致异常,但不会产生有意义的函数结果。在这个特定的例子中,if
条件保护您免受该情况的影响,但在更复杂的情况下,如果该条件位于函数体之外,则使用部分函数将成为潜在的bug。这就是为什么它作为一种普遍做法不被鼓励的原因
但我还必须指出,您不应该对
if-else
结构表示普遍的不满。它是一个完全有效的函数表达式,有它的用途。只是在这个特定的例子中,这是一个次优的方法。我个人认为有两种方法更好:
def pair(s: String) = s.split(":") match {
case Array(k, v) => Some(k.trim -> v.trim)
case _ => None
}
或者使用Scala方便的正则表达式提取器:
val Pair = """\s*([^\s:]+)\s*:\s*([^\s:]+)\s*""".r
def pair(s: String) = s match {
case Pair(k, v) => Some(k -> v)
case _ => None
}
但是,你的也没那么糟糕。我更喜欢第1种方法:)你能描述一下为什么它们看起来更漂亮吗?使用条件表达式没有什么错,但它们通常更具命令性或过程性(“检查这个!”,“做那个!”),模式匹配通常感觉更具声明性,我倾向于使用声明性代码。你说得对<代码>如果看起来像贾拉而不是真正的斯卡拉。@迈克尔不必在意事情的外观。模式匹配更适合这种特殊情况,还有更重要的原因。我已经在更新我的答案时解释过了。@NikitaVolkov谢谢。很好的解释。为了消除歧义,
Some(a,b)
应该用Some((a,b))
显式标识Tuple2。