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
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
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

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