Scala <member> не является членом <class>

У меня есть набор классов scala, которые я пытаюсь использовать:

FileA.scala

abstract class ResourceType[T](val amount: T) {
}

class Cpu(amount: Double) extends ResourceType[Double](amount){
}

class Memory(amount: ByteSize) extends ResourceType[ByteSize](amount){
}


class Storage(amount: ByteSize) extends ResourceType[ByteSize](amount){
}

class RuntimeResources(cpus: Double = 1, memSize: ByteSize = 0.B, storageSize: ByteSize = 0.B) {
  val cpu: Cpu = new Cpu(cpus)
  val mem: Memory = new Memory(memSize)
  val storage: Storage = new Storage(storageSize)
}

Затем где-то еще в кодовой базе (другой файл, тот же пакет), FileB.scala

...
val x: Seq[RuntimeResources] = ...
...
x.map(_.mem.amount.toMB)

Однако, когда я пытаюсь скомпилировать это, я получаю

value amount is not a member of <package>.Memory

Я думаю, что неправильно понимаю модификаторы доступа классов. Я действительно не понимаю, почему это не компилируется. Когда я перемещаю классы из FileA.scala в FileB.scala, кажется, что они компилируются нормально, однако я не могу переместить код в этот файл по другим причинам. Почему простое перемещение кода из FileA.scala в FileB.scala позволяет его скомпилировать, и есть ли способ обойти это?

Что такое resources в функции карты?

AminMal 18.12.2020 21:27

О, хороший момент. Я понял, что ошибся с типом x при преобразовании кода. Это должно быть просто _.mem.amount.toMB. Я обновил вопрос.

zac 18.12.2020 21:34

Не могли бы вы создать репозиторий github, воспроизводящий эту проблему?

Tomer Shetah 20.12.2020 08:19
Стоит ли изучать 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
258
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я нашел причину, по которой это не будет компилироваться.

Я работаю с большой кодовой базой (100 000+ LoC), и в другом файле в том же пакете был sealed trait Memory, который конфликтовал с классом Memory в функции выше.

Когда я переименовал один из классов, он скомпилировался нормально. Я удивлен, что компилятор не отмечает это как проблему. Казалось, что эта черта имеет приоритет в компиляторе.

Редактировать: после обсуждения в комментариях я зарегистрировал ошибку в scala для этой проблемы: https://github.com/scala/bug/issues/12289

«Я удивлен, что компилятор не помечает это как проблему», что помечает как проблему?

Luis Miguel Mejía Suárez 18.12.2020 21:46

Столкновение трейта и одноименного класса в одном пакете — в моем случае это было Memory. Компилятор не дал никакого представления о том, что в пакете есть другой объект с таким же именем.

zac 18.12.2020 21:52

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

Luis Miguel Mejía Suárez 18.12.2020 21:55

Да, я на 100% уверен, что все в одной упаковке. Это не предупредило или не выдало ошибку о конфликте имени. Хотя я только что понял, что файлы на самом деле существуют в разных модулях sbt. Таким образом, первый модуль, скажем, A, компилируется нормально, но конфликт имен возникает в другом модуле SBT, скажем, B. Одно и то же имя пакета используется в модулях A и B.

zac 18.12.2020 22:02

Извините, я отредактировал свой предыдущий комментарий - см. выше. Я заметил, что пакет scala фактически разделен на отдельные модули SBT. Первый модуль компилируется нормально, второй модуль определяет зависимость от первого и внутри пакета объявляет конфликтующее имя

zac 18.12.2020 22:08

Вы правы, я только что проверил это. Это звучит как ошибка; хотите сообщить об этом?

Luis Miguel Mejía Suárez 18.12.2020 22:22

Я зарегистрировал эту ошибку: github.com/scala/bug/issues/12289

zac 18.12.2020 23:17

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