Как ссылаться на подклассы статических классов Java с обобщениями в Scala - PullRequest
5 голосов
/ 26 июля 2010

У меня есть этот код Java:

public class TestMapper extends AppEngineMapper<Key, Entity, NullWritable, NullWritable> {
  public TestMapper() {
  }
// [... other overriden methods ...]
      @Override
      public void setup(Context context) {
        log.warning("Doing per-worker setup");
      }
}

... который я преобразовал в:

class TestMapper extends AppEngineMapper[Key, Entity, NullWritable, NullWritable] {
// [... other overriden methods ...]
      override def setup(context: Context) {
        log.warning("Doing per-worker setup")
      }
}

Теперь актуальная проблема:

Контекст определяется как вложенный класс в org.apache.hadoop.mapreduce.Mapper class:

        public static class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>   {
    //[... some other methods ...]
protected void setup(org.apache.hadoop.mapreduce.Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>.Context context) throws java.io.IOException, java.lang.InterruptedException { /* compiled code */ }
        public class Context extends org.apache.hadoop.mapreduce.MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {

        public Context(org.apache.hadoop.conf.Configuration configuration, org.apache.hadoop.mapreduce.TaskAttemptID conf, org.apache.hadoop.mapreduce.RecordReader<KEYIN,VALUEIN> taskid, org.apache.hadoop.mapreduce.RecordWriter<KEYOUT,VALUEOUT> reader, org.apache.hadoop.mapreduce.OutputCommitter writer, org.apache.hadoop.mapreduce.StatusReporter committer, org.apache.hadoop.mapreduce.InputSplit reporter) throws java.io.IOException, java.lang.InterruptedException { /* compiled code */ }

        }

Так что я не могу сказать своему классу Scala, где / что Context на самом деле. Если бы Mapper не имел обобщений, я мог бы сослаться на Context через

Mapper#Context

но как я могу сказать, что у Mapper есть Generics?

Mapper[_,_,_,_]#Context

... не работал.

Ответы [ 2 ]

9 голосов
/ 26 июля 2010

Вы должны предоставить точный базовый тип для вашей проекции типа, в вашем случае

Mapper[Key, Entity, NullWritable, NullWritable]#Context

поэтому переопределение setup будет записано как

override def setup(context: Mapper[Key, Entity, NullWritable, NullWritable]#Context)

Использование можно упростить, введя псевдоним типа

class TestMapper extends AppEngineMapper[Key, Entity, NullWritable, NullWritable] {

  type Context = Mapper[Key, Entity, NullWritable, NullWritable]#Context

  override def setup(context: Context) = {
      // ...
   }
}

Если вы хотите написать несколько картографов, вы можете преобразовать это в черту, которую можно смешать с вашей реализацией:

trait SMapper[A,B,C,D] extends Mapper[A,B,C,D] {
  type Context = Mapper[A,B,C,D]#Context
}

class TestMapper extends AppEngineMapper[Key, Entity, NullWritable, NullWritable]
                    with SMapper[Key, Entity, NullWritable, NullWritable] {
  override def setup(context: Context) = {
     // ...
  }
}

или для простого hadoop:

class TestMapper extends SMapper[Key, Entity, NullWritable, NullWritable] {
  override def setup(context: Context) = {
     // ...
  }
}
0 голосов
/ 22 мая 2012

Проблемы, которые иногда возникают у людей при использовании принятого ответа, связаны с ошибкой в ​​компиляторе Scala ( ссылка ).

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