这些天我正在努力学习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
}
}
}
提前致谢:)
答案 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
非常有说服力的评论:在术语和类型级别上强调为通配符,以及将方法强制转换为第一类函数的方法。