Возможны ли приведения в скале? - PullRequest
1 голос
/ 28 февраля 2012

У меня есть следующий метод:

 def generateTokenForAccount(account: Account): Account = {
    account.setAccountToken(UUID.randomUUID().toString())
    return account
  }

Я передаю этому методу подкласс Account, т.е. ChildminderAccount, и пытаюсь привести результат в scala безрезультатно. Что я делаю не так?

@Transactional
  def registerChildminderAccount(childminderAccount: ChildminderAccount): Boolean = {
    childminderAccountDAO.save((ChildminderAccount) generateTokenForAccount(childminderAccount))//problem here!!
    if (mailerService.requestChildminderConfirmation(childminderAccount)) {
      return true
    } else {
      return false
    }
  }

Я получаю следующую ошибку: value generateTokenForAccount is not a member of object com.bignibou.domain.ChildminderAccount, как если бы я вызывал generateTokenForAccount в классе ChildminderAccount.

Может кто-нибудь помочь, пожалуйста?

Ответы [ 4 ]

10 голосов
/ 28 февраля 2012

Вы можете использовать здесь приведение, но в целом в Scala asInstanceOf - это запах кода (как и return). Вместо этого попробуйте следующее:

def generateTokenForAccount[A <: Account](account: A): A = {
  account.setAccountToken(UUID.randomUUID.toString)
  account
}

Теперь, если вы введете ChildminderAccount, вы получите ChildminderAccount.

4 голосов
/ 28 февраля 2012

Может потребоваться использовать «матч» для лучшей обработки ошибок

generateTokenForAccount(childminderAccount) match {
  case acc: ChildminderAccount => childminderAccountDAO.save( acc )
  case _ => // ERROR
}
4 голосов
/ 28 февраля 2012
generateTokenForAccount(childminderAccount).asInstanceOf[ChildminderAccount]
0 голосов
/ 28 февраля 2012

Почему generateTokenForAccount возвращает свой ввод? Это обманчиво, потому что это приводит вас к мысли, что он создает новый, измененный объект, тогда как на самом деле это не так; вместо этого он мутирует переданный объект. Он должен возвращать Unit, чтобы указать это:

def generateTokenForAccount(account: Account) {
  account.setAccountToken(UUID.randomUUID().toString())
}

Теперь тип подсказывает, что вы можете просто использовать эффект в последовательности:

def registerChildminderAccount(childminderAccount: ChildminderAccount): Boolean = {
    generateTokenForAccount(childminderAccount)
    childminderAccountDAO.save(childminderAccount)
    mailerService.requestChildminderConfirmation(childminderAccount)
  }

Также, когда у вас есть if foo { return true } else { return false }, это эквивалентно return foo. В Scala последнее выражение в блоке возвращается автоматически, поэтому вы даже можете удалить ключевое слово return.

...