为什么scala在给出这个模式匹配的积分值时会抱怨?

Fra*_*ery 3 scala pattern-matching

目标:编写一个函数,生成一个新的String,不包括指定的字符(由索引标识)

示例:

  • takeAllExcept(0, "abc") 回报 bc
  • takeAllExcept(1, "abc") 回报 ac
  • takeAllExcept(2, "abc") 回报 ab

我最初做了什么:

def takeAllExcept( index: Int, s: String ): String = {
  val lastIndex = s.length()-1
  index match {
    case 0 => return s.slice(1, s.length)
    case lastIndex => return s.slice(0, s.length()-1)
    case _ => { s.slice(0, index) + s.slice(index+1, s.length) }
  }
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨语句块case _无法访问.

我是如何修理它的

def takeAllExcept( index: Int, s: String ): String = {
  val lastIndex = s.length()-1
  if( index == 0 )
    return s.slice(1, s.length)

  if( index == lastIndex )
    return s.slice(0, s.length()-1)

  s.slice(0, index) + s.slice(index+1, s.length)
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么我的初始尝试因无法访问的代码而失败.它看起来很合法.此外,scala中是否有内置设施可以执行此操作?

Mar*_*ing 10

lastIndex在模式中是一个新名称的隐式声明,它绑定到匹配的任何值和阴影allready定义lastIndex,正如另外两个post已经指出的那样.还有两种可能性,而不是使用大写标识符(参见Peter的帖子):

使用反引号让编译器知道这不应该是新标识符的声明:

case `lastIndex` => ...
Run Code Online (Sandbox Code Playgroud)

使用图案防护:

case x if x == lastIndex => ...
Run Code Online (Sandbox Code Playgroud)

如果你想对字符串进行大量基于索引的删除,那么通过调用toBuffer字符串来使用Buffer会更快,然后你可以使用remove(i: Int)Buffer 的方法.这对于一个操作来说速度较慢,因为你必须在完成后将Buffer转换回字符串,但如果你做了很多随机访问操作,它会快得多.完成后,您可以调用mkStringBuffer来获取String.对于单一删除,我会像彼得建议的那样做,或者这里是另一种选择:

def takeAllExcept(i: Int, s: String) = s.take(i) + s.drop(i+1)
Run Code Online (Sandbox Code Playgroud)


Pet*_*itz 6

你的第一个问题:

def takeAllExcept( index: Int, s: String ): String = {
  val LastIndex = s.length()-1
  index match {
    case 0 => return s.slice(1, s.length)
    case LastIndex => return s.slice(0, s.length()-1)
    case _ => { s.slice(0, index) + s.slice(index+1, s.length) }
  }
}
Run Code Online (Sandbox Code Playgroud)

lastIndex之后的case是新绑定而模式匹配和隐藏的定义val lastIndex = s.length()-1.正如我的示例所示,您可以使用大写名称,然后scala使用val范围中定义的内容.

要以某种方式回答你的第二个问题我会解决它:

def takeAllExcept(i: Int, s: String): String = {
  val (prefix,suffix) = s.splitAt(i)
  prefix + suffix.tail
}
Run Code Online (Sandbox Code Playgroud)

  • 这很容易:阅读"Scala编程"一书,自己做一些项目,阅读许多博客和stackoverflow条目,永远不要停止尝试疯狂的方法;) (2认同)