Как разделить объект на подклассы с var в его основном конструкторе

Я рекомендовал бы против фактической генерации блоков, если Вы абсолютно не должны, особенно если Вы просто начинаете с реализацией генетического алгоритма.

генетический алгоритм является самым легким реализовать, когда выходной язык функционален и с динамическим контролем типов. Это обычно, почему большая часть исследования генетического алгоритма записана в LISP. В результате, если Вы собираетесь реализовать его в C#, Вы - вероятно, более обеспеченное определение Вашего собственного мини-"древовидного языка", наличие алгоритма генерируют деревья и просто интерпретацию деревьев, когда это прибывает время для выполнения каждого повторения алгоритма.

я сделал проект как это, когда я был в колледже (реализация генетического алгоритма в C#), и это было подходом, который я проявил.

Выполнение его тот путь даст Вам преимущество только наличия 1 представления для работы с (представление AST), который оптимально подходит и для выполнения и для шагов "воспроизведения" генетического алгоритма.

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

Интерпретируемый AST, с другой стороны, является предметом коллекционирования мусора точно так же, как любой другой объект, и таким образом, Вам не было бы нужно обезьяне вокруг с несколькими доменами приложения. Если, для производительности обосновывает, что Вы хотите генералу кода конечный результат, можно добавить поддержку этого позже. Однако я, Вы рекомендовали бы сделать то использование класс DynamicMethod . Это позволит Вам преобразовывать AST в скомпилированного делегата динамично во времени выполнения. Это позволит Вам развернуть единственный DLL при сохранении материала генерации кода максимально простым. Кроме того, экземпляры DynamicMethod являются предметом коллекционирования мусора, таким образом, Вы могли закончить тем, что наняли их как часть генетического алгоритма для ускорения вещей там также.

7
задан Trenton 17 November 2009 в 09:57
поделиться

4 ответа

Вам не нужно объявлять var в сигнатуре конструктора подкласса:

class B (val name: String, /* note no var */ updateCount: Int) extends A(updateCount) {
  //...
}

Это также распространяется на классы с val s в их также конструкторы:

scala> class C(val i: Int)
defined class C

scala> class D(j: Int) extends C(j)
defined class D
7
ответ дан 6 December 2019 в 19:38
поделиться

Необходимо избегать того, чтобы идентификатор, объявленный для B , дублировал идентификатор, объявленный для A . Самый простой способ сделать это - выбрать другое имя. Если, однако, вы действительно не хотите этого делать, вот альтернатива:

class B (val name: String, updateCount: Int) extends A(updateCount) {
  self: A =>
  def inc(): Unit = {
    self.updateCount = self.updateCount + 1
  }
}

И, кстати, удалите var из объявления B.

4
ответ дан 6 December 2019 в 19:38
поделиться

Когда вы используете ключевое слово var в параметрах, это делает переданное значение новой var в классе. Когда вы этого не делаете, он делает его параметром конструктора (только), и вы используете его значение для var , передавая его конструктору. Итак, пример, приведенный людьми

class B(val name:String, updateCount:Int) extends A(updateCount)

, верен.

Однако scala делает параметры конструктора напрямую доступными для методов в классе (я не уверен, почему), поэтому, если вы используете то же имя, вы обнаружите, что ваш код не может быть скомпилирован с ошибкой переназначение val , когда вы пытаетесь переназначить "var". Например, в следующем фрагменте неизменяемый параметр конструктора затеняет унаследованную var , и поэтому вы не можете присвоить этому параметру.

class B (val name: String, updateCount: Int) extends A(updateCount) {
  def inc(): Unit = {
    updateCount = updateCount + 1
  }
}
2
ответ дан 6 December 2019 в 19:38
поделиться

Как отмечают другие, ваш параметр конструктора в B дублирует версию суперкласса. Вот код, который работает и не требует самостоятельного ввода:

class A (var updateCount: Int) {
}

class B (val name: String, uc: Int) extends A(uc) {
  def inc(): Unit = {
    updateCount = updateCount + 1
  }
}
0
ответ дан 6 December 2019 в 19:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: