Scala: параметризация типа с одним из его внутренних типов - PullRequest
2 голосов
/ 13 октября 2010

Я хотел бы параметризовать тип с одним из его подклассов.Рассмотрим следующее:

class DataLoader {
  class Data { /* data specifics to this data loader */ }
  def getData : Data /* and so on */
}

Теперь я хочу, чтобы этот загрузчик мог асинхронно получать данные из сети.Один из вариантов заключается в том, чтобы иметь его подкласс Callable.

class DataLoader extends Callable[Data] {
  class Data { /* ... */ }
  def call : Data = { ... }
}
val futureData = executor.submit(new DataLoader)
futureData.get

Scala не позволит мне сделать это, потому что, когда я предоставляю параметры Callable, Data еще не известен.Если я напишу DataLoader.Data, Scala отзовет меня для циклической ссылки.

Конечно, я мог бы написать свой класс данных вне моего загрузчика, но бывают случаи, когда он лучше внутри.Конечно, другой альтернативой было бы иметь, скажем, DataManager с внутренним типом данных и загрузчиком, расширяющим Callable [Data] - что в этом случае, возможно, является лучшим дизайном.Но в стороне от этих проблем, есть ли какой-нибудь способ, которым я действительно могу реализовать черту, которая включает в себя написание функции, возвращающей T, устанавливая T как внутренний класс?

Ответы [ 3 ]

4 голосов
/ 13 октября 2010

Есть миллион способов достичь чего-то разумного, поэтому сложно ответить. Я не думаю, что вы хотите слишком привязаться к идее параметризации супертипа в одном из собственных внутренних классов подтипа. Даже если это сработает, это не сработает.

Из миллиона способов я выбрал что-то наугад, и оказалось, что это связано с инверсией. Я сделал это так, потому что вы сказали в комментарии, что не можете заставить его скомпилироваться в объекте-компаньоне, и я не уверен, почему это будет.

import java.util.concurrent.Callable

class DataLoader extends Callable[DataLoader.Data] {
  def call = new DataLoader.Data(this)
}

object DataLoader {
  private class Data(loader: DataLoader) {
  }
}
2 голосов
/ 13 октября 2010

Поместите класс в объект-компаньон.

2 голосов
/ 13 октября 2010

А как насчет этого? trait Callable { type TData def getData: TData } class DataLoader extends Callable { type TData = Data class Data override def getData: TData = new Data }

Edit: Извините, не заметил, что вы имели в виду Callable из java.util.concurrent .. Тогда добавление следующего может помочь: implicit def c2c[T](c: Callable {type TData = T}) = new java.util.concurrent.Callable[T] { def call = c.getData }

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