Scala的第一步

时间:2012-03-06 10:03:30

标签: scala

这些天我正在努力学习scala。

我对_运算符感到困惑。 我如何在以下程序中使用它?

此程序如何更简洁?

我了解到scala推广使用val而不是var,在这种情况下,我们如何才能将val用于balance

private object Main {

  def main(args: Array[String]): Unit = {
    val acc1 = new PiggyBank(5)
    acc1.printBalance
    acc1 deposit 5
    acc1.printBalance
    acc1 withdraw 5
    acc1.printBalance
  }
}

private class PiggyBank(open_Bal: Int) {
  var balance = open_Bal
  def deposit(value: Int) = balance = balance + value
  def printBalance = println(balance)
  def iswithdrawable(value: Int) =  balance >= value
  def withdraw(value: Int) = {
    if (iswithdrawable(value)) {
      balance = balance - value
    }
  }
}

提前致谢:)

4 个答案:

答案 0 :(得分:9)

你可能会在这里得到一百万个答案:)但是,根据你问题的内容,你需要阅读一本书。我推荐Programming in Scala 2nd Edition。我已经读了两遍,它在这个过程中得到了狗耳和咖啡染色。

我之所以这么说是因为Scala为您提供了一个新的范例,并且您正在Scala中编写Java代码。这对初学者来说非常好,但是你不会以这种方式学习你想学的东西。这本书是一个很好的开始,它将为您提供了解更多信息的基础。

例如,以下是我在代码中更改的内容:

case class PiggyBank(balance: Double) {
  def deposit(amount: Double) = PiggyBank(balance + amount)
  def withdraw(amount: Double): Option[PiggyBank] = {
    if (balance >= amount) Some(PiggyBank(balance - amount))
    else None
  }
  override def toString() = balance.toString
}

但是“为什么”我想这样做才是真正的问题,我认为这是你真正需要回答的问题。简而言之,它是不可变的,而且功能更强大(虽然,这是一个玩具示例,这里有很大的改进空间),但为什么会这样,为什么我们关心呢?书籍回答了这个问题。

鉴于此,如果需要,您可以开始使用_。例如:

val result = PiggyBank(500) withdraw 200 flatMap { _.withdraw(200) } 
println(result.getOrElse(0))

但是,如果你像大多数人一样(就像我很久以前的那样),你会问“为什么地球上那更好?”。这不是你在快速SO帖子中找到的答案。我可以继续下去,但最重要的是有那些已经完成的书,并且做得比我做得好。

答案 1 :(得分:4)

这里没有必要_。 _不是运算符,而是闭包中参数的占位符。例如。当你给foldLeft调用一个整数集合给你总结时,你可以写List(1,2,3,4).foldLeft(0)(_ + _)而不是List(1,2,3,4).foldLeft(0)((x,y) => x + y)。第一个_将是第二个示例中的x,第二个是y。

答案 2 :(得分:2)

您将val与不可变对象一起使用。由于您的PiggyBank是可变的,因此可变内部状态需要var

你可以用这种方式变换你的PiggyBank(基本上每个操作都会创建一个新的不可变对象来改变对象的状态):

class PiggyBank(val balance : Int) {
  def deposit(value: Int) = new PiggyBank(balance + value)

  def printBalance = println(balance)
  def iswithdrawable(value: Int) =  balance >= value

  def withdraw(value: Int) = if (iswithdrawable(value)) new PiggyBank(balance - value) else this;
  }

所以你可以这样写:

object Main {

    def main(args: Array[String]): Unit = {
       val acc1 = new PiggyBank(5) deposit 5 withdraw 5
       acc1.printBalance
  }

答案 3 :(得分:1)

关于下划线/通配符,这些是有用的读取,在惯用代码中经常遇到“_”:

http://www.slideshare.net/normation/scala-dreaded

http://agileskills2.org/blog/2011/05/01/revealing-the-scala-magicians-code-expression/


Staircase vers的书籍索引。 2有“_”的7个条目:

“curried functions”,“existential types”,“function literals”,

“in identifiers”“import statements”“match expressions”和“initialize field to default value”

http://www.artima.com/pins1ed/book-index.html#indexanchor


非常有说服力的评论:在术语和类型级别上强调为通配符,以及将方法强制转换为第一类函数的方法。

http://lambda-the-ultimate.org/node/2808#comment-41717