Передача параметров, сделанных в классе Case, в признак

Контекст

Ради возможности менять конфиг для тестирования у меня есть трейт почти со всем кодом. Затем в классе case я пытаюсь передать конфигурацию. В моем тестировании у меня есть класс тестового случая.

Это работает (но это не та функциональность, которую я хочу)

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class prodEnvClass extends Greeting("Production Env") {
  println(msg)
}

class testEnvClass extends Greeting("Testing Env") {
  println(msg)
}

Это не работает (но это функциональность, которую я хочу)

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class prodEnvClass extends Greeting(myEnv) {
  val myEnv = fetchProdEnv()
  println(msg)
}

class testEnvClass extends Greeting(myEnv) {
  val myEnv = fetchTestEnv()
  println(msg)
}

Вопрос

Как передать параметр, созданный внутри тела класса case, в трейт? Код, который работает, не соответствует моему варианту использования. Я хочу использовать код внутри класса case, чтобы сделать ввод в черту.

Вы не можете AFAIK. (кстати, я также не вижу case class в вашем коде). Как бы вы инициализировали это? Вам нужно инициализировать трейт, чтобы инициализировать класс, но вам также нужно инициализировать класс, чтобы инициализировать трейт? Тут же конфликт. Вы должны сделать класс final и иметь сопутствующий объект, инициализирующий класс по мере необходимости. Он может загрузить требуемый конфиг и передать его дальше. Вы можете использовать ciris для загрузки в соответствующих средах.

sinanspd 15.12.2020 06:37

Хотя я должен отметить, вы могли бы использовать имя метода в качестве параметра. Это простое решение, но я бы так не придумал.

sinanspd 15.12.2020 06:43

Есть похожий пост, в котором та же функциональность нужна для другой цели: Расширить абстрактный класс Java в Scala

Tomer Shetah 15.12.2020 08:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
150
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Для вызова функции вы

  • создать привязки как параметры функции, а затем
  • передавать значения в качестве аргументов,

что-то вроде этого:

def f(s: String) { println(s) }
f("hello (function invocation)")

При использовании наследования вы

  • создавать связыватели, называя абстрактные члены, а позже вы
  • передавать значения, предоставляя реализации для этих абстрактных членов

что-то вроде этого:

trait C { def s: String; def m() = println(s) }
new C { val s = "hello (inheritance)"; m() }

В вашем коде вы, кажется, пытаетесь

  • привязать значение как параметр конструктора (как и для функций)
  • передать значение myEnv, переопределив его по-разному в двух подклассах (как вы сделали бы для наследования)

Просто выберите один механизм. Если вы хотите наследование, сделайте наследование:

class MyEnv(val name: String)

trait Greeting {
  def myEnv: MyEnv
  def msg = s"hello ${myEnv.name}"
}

def fetchProdEnv() = new MyEnv("prod")
def fetchTestEnv() = new MyEnv("test")

class ProdEnvClass extends Greeting {
  val myEnv = fetchProdEnv()
  println(msg)
}

class TestEnvClass extends Greeting {
  val myEnv = fetchTestEnv()
  println(msg)
}

new ProdEnvClass() // "hello prod"
new TestEnvClass() // "hello test"

но не пытайтесь использовать две половинки (по половинке от каждого механизма), они так не смешиваются.

Другие вопросы по теме