Это правильный способ перевода интерфейса Java в Scala? - PullRequest
1 голос
/ 27 января 2012

Я начинаю изучать Scala и сделаю простой кросс-компилятор.

Я буду поддерживать небольшой набор инструкций, таких как print.

Примечание: фрагменты кода не проверяютсяскомпилирован.Вот что я бы сделал в JAVA.

public interface Compiler{
 String getPrintInstruction();
}

public class JavaCompiler implements Compiler{
 public String getPrintInstruction(){
  return "System.out.print(arg0);"
 }
}

public class ScalaCompiler implements Compiler{
 public String getPrintInstruction(){
  return "print(arg0);"
 }
}

Является ли фрагмент ниже правильного "Scala way "?

trait Compiler {
  var printInstruction: String
}
class JavaCompiler extends Compiler {
  var printInstruction = "System.out.print(arg0);"
}
class ScalaCompiler extends Compiler {
  var printInstruction = "print(arg0);"
}

РЕДАКТИРОВАТЬ:

Я перенесу свой второй вопрос в новую тему.

Ответы [ 3 ]

2 голосов
/ 27 января 2012

Для отображения 1: 1 эти var s должны быть изменены на def s.

trait Compiler {
  def printInstruction: String
}

class JavaCompiler extends Compiler {
  def printInstruction = "System.out.print(arg0);"
}

class ScalaCompiler extends Compiler {
  def printInstruction = "print(arg0);"
}

def объявляет метод.Когда вы не предоставляете реализацию, она становится абстрактным методом.

РЕДАКТИРОВАТЬ:

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

1) Дискриминационные союзы.(он же типы сумм.)

Обратитесь к этой превосходной статье , чтобы узнать об этой концепции.Вот как ваш пример, вероятно, выглядел бы при моделировании таким образом:

sealed trait Compiler {
  def printInstruction: String = this match {
    case JavaCompiler => "System.out.print(arg0);"
    case ScalaCompiler => "print(arg0);"
  }
}

case object JavaCompiler extends Compiler
case object ScalaCompiler extends Compiler

2) Тип шаблона класса.

Здесь - отличный пост Даниэля СобралаЭта тема.Вы можете найти еще несколько вещей, прибегая к помощи терминов тип-класс, шаблон, Scala, имплициты и т. Д. Вот как может выглядеть ваш код, если проблема смоделирована с помощью шаблона класса типа:проблема, оригинальный подход и подход дискриминированных союзов, кажется, лучшие решения для моделирования.

1 голос
/ 27 января 2012

Самый идиоматический способ - использовать def для абстрактных свойств и val для конкретных свойств только для чтения.В соответствии с принципом унифицированного доступа , val может использоваться для реализации метода:

trait Compiler {
  def printInstruction: String
}

class JavaCompiler extends Compiler {
  val printInstruction = "System.out.print(arg0);"
}

class ScalaCompiler extends Compiler {
  val printInstruction = "print(arg0);"
}
0 голосов
/ 27 января 2012

Почему я должен повторно объявить переменную еще раз в классе, если объявил ее в признаке?

Поскольку вы объявили сигнатуру метода printInstructionно ты не сказал, что он сделал.В class, поскольку это не abstract class, должны быть определены все функции.Кстати, вы могли бы определить printInstruction непосредственно в trait Compiler, если предполагается, что он должен делать то же самое в каждой реализации.

...