Нулевой метод с универсальным типом возврата - PullRequest
1 голос
/ 06 марта 2019

У меня есть следующий код, который должен быть фабричным классом.Его метод apply имеет универсальный параметр для ограничения возвращаемого типа:

sealed trait Account
final case class CheckingAccount() extends Account
final case class SavingsAccount() extends Account

object Account {
    def apply[T <: Account]:T = {
        CheckingAccount()   // CheckingAccount().asInstanceOf[T]
    }
}

Но компилятор сообщает "Выражение типа Banking.CheckingAccount не соответствует ожидаемому типу T", если не выполняется явное преобразование типа,Кто-нибудь знает почему?

1 Ответ

6 голосов
/ 06 марта 2019

Метод подписи

def apply[T <: Account]: T 

гарантирует, что для каждого T, который является подтипом Account, вы можете получить T.

В частности,

Account.apply[Nothing]

должен "вернуть" экземпляр Nothing. Поскольку экземпляров Nothing нет, единственный способ реализовать такой метод - выдать ошибку / исключение. Другими словами, сигнатура вашего метода требует так мало и обещает столько , что метод становится практически невыполнимым.


Обходной путь 1

Удалить аргумент типа. Вернуть Account.


Обходной путь 2

Если вы хотите сохранить общий тип возвращаемого значения, вы можете попробовать что-то вроде этого:

sealed trait Account
final case class CheckingAccount() extends Account
final case class SavingsAccount() extends Account

trait Default[X] {
  def createDefault: X
}

implicit object DefaultCheckingAccount extends Default[CheckingAccount] {
  def createDefault = CheckingAccount()
}

implicit object DefaultSavingsAccount extends Default[SavingsAccount] {
  def createDefault = SavingsAccount()
}

object Account {
    def apply[T <: Account](implicit d: Default[T]): T = d.createDefault
}

Account[SavingsAccount]
Account[CheckingAccount]

Он компилируется, но выглядит несколько избыточным (какой смысл вызывать Account[SavingsAccount] вместо просто SavingsAccount()?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...