У меня есть набор классов 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
позволяет его скомпилировать, и есть ли способ обойти это?
О, хороший момент. Я понял, что ошибся с типом x
при преобразовании кода. Это должно быть просто _.mem.amount.toMB
. Я обновил вопрос.
Не могли бы вы создать репозиторий github, воспроизводящий эту проблему?
Я нашел причину, по которой это не будет компилироваться.
Я работаю с большой кодовой базой (100 000+ LoC), и в другом файле в том же пакете был sealed trait Memory
, который конфликтовал с классом Memory
в функции выше.
Когда я переименовал один из классов, он скомпилировался нормально. Я удивлен, что компилятор не отмечает это как проблему. Казалось, что эта черта имеет приоритет в компиляторе.
Редактировать: после обсуждения в комментариях я зарегистрировал ошибку в scala для этой проблемы: https://github.com/scala/bug/issues/12289
«Я удивлен, что компилятор не помечает это как проблему», что помечает как проблему?
Столкновение трейта и одноименного класса в одном пакете — в моем случае это было Memory
. Компилятор не дал никакого представления о том, что в пакете есть другой объект с таким же именем.
Вы уверены, что это было в той же упаковке? Я почти уверен, что в этом случае компилятор не только предупреждает, но и выдает ошибки. Однако, если они у вас есть в разных пакетах и импортированы в одно и то же место, тогда да, второй импорт переопределит первый, который является базовым управлением пространством имен.
Да, я на 100% уверен, что все в одной упаковке. Это не предупредило или не выдало ошибку о конфликте имени. Хотя я только что понял, что файлы на самом деле существуют в разных модулях sbt. Таким образом, первый модуль, скажем, A, компилируется нормально, но конфликт имен возникает в другом модуле SBT, скажем, B. Одно и то же имя пакета используется в модулях A и B.
Извините, я отредактировал свой предыдущий комментарий - см. выше. Я заметил, что пакет scala фактически разделен на отдельные модули SBT. Первый модуль компилируется нормально, второй модуль определяет зависимость от первого и внутри пакета объявляет конфликтующее имя
Вы правы, я только что проверил это. Это звучит как ошибка; хотите сообщить об этом?
Я зарегистрировал эту ошибку: github.com/scala/bug/issues/12289
Что такое
resources
в функции карты?