2012-03-06 6 views
3

Я пытаюсь изучить 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 
    } 
    } 
} 

Заранее спасибо :)

+0

Я SCALA n00b, но я думаю, баланс должен быть 'var'. И 'var' целенаправленно делается для выполнения этих задач, чтобы вы могли его мутировать. – Nishant

+0

любое представление о '_' .. как я могу использовать его здесь? – Shrey

+0

Я, с ограниченными возможностями в Scala, не смог найти место, где вы бы использовали '_', если вы его не нажмете. – Nishant

ответ

9

Здесь вы, вероятно, получите миллион ответов :) Но, основываясь на содержании вашего вопроса, вам нужно прочитать книгу. Я бы порекомендовал Programming in Scala 2nd Edition. Я читал его дважды, и он получил собаку и кофе, окрашенный в процессе.

Причина, по которой я говорю, объясняется тем, что Scala представляет вам новую парадигму, и вы пишете Java-код в Scala. Это отлично подходит для начинающих, но вы не узнаете, чему хотите научиться. Книга - отличное начало, которое даст вам фундамент, чтобы узнать больше.

К примеру, вот что я бы изменить в коде:

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)) 

Но если вы похожи на большинство нубов (как я давным-давно), вы собираетесь спросить «Почему на земле является то, что лучше ??». Это не ответ, который вы найдете в быстрой почте. Я мог бы продолжать, продолжать и продолжать, но суть в том, что есть книги, которые уже сделали это, и сделали это лучше, чем я могу.

+0

Thnk вы так много .. m читаете Программирование в Scala .. но было смущено с применением знания .. – Shrey

+0

Awesome! Хорошая вещь. Тогда все, что я могу сказать, просто дайте ему время. :) Вы явно на ранних этапах книги; больше станет ясно, когда вы продолжите. –

+0

да .. Мне жаль, что для него не было видеоуроков .. – Shrey

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 
    } 
+0

в основном создать новый объект вместо изменения внутреннего состояния? – Shrey

+0

@ Шрей да. Поверните каждую операцию, изменив внутреннее состояние на функцию, возвратите новый объект с новым внутренним состоянием – onof

+0

большое вам спасибо. :) – Shrey

4

Здесь не нужно _ здесь. _ не является оператором, а заполнитель для параметров в замыканиях. Например. когда вы вызываете foldLeft - набор целых чисел, которые вы суммируете, вы можете написать List(1,2,3,4).foldLeft(0)(_ + _) вместо List(1,2,3,4).foldLeft(0)((x,y) => x + y). Первый _ будет x во втором примере, а второй _ y.

+1

I получи.. ! спасибо .. :) – Shrey

1

Что касается подчеркивания/маски, это полезно читает, "_" часто встречается в идиоматическом коде:

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

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


индекс Книги для ЛЕСТНИЧНОГО вара. 2 имеет 7 записей для «_»:

«выделанные функции», «экзистенциальные типы», «функциональные литералы»,

«в идентификаторах» «операторов импорта» «соответствуют выражения» и «инициализировать поле по умолчанию значение»

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


очень красноречивый комментарий: подчеркивание в качестве шаблона как на курсовой и типе уровне плюс как способ принуждения метод в первую функцию класса.

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

+0

thnxx Gene .. :) – Shrey

Смежные вопросы