Scala, переопределяющий неабстрактное определение с var

Обновление
, В то время как то, что я пишу ниже, верно как общий ответ об общих библиотеках, я думаю, что самая частая причина этих видов сообщения состоит в том, потому что Вы установили пакет, но не установили "-dev" версию того пакета.

ну, это не лежит - нет никакого libpthread_rt.so.1 в том списке. Вероятно, необходимо реконфигурировать и восстановить его так, чтобы это зависело от библиотеки, Вы имеете или устанавливаете то, что обеспечивает libpthread_rt.so.1.

Обычно числа после .so являются номерами версий, и Вы будете часто находить, что они - символьные ссылки друг на друга, поэтому если у Вас будет версия 1.1 libfoo.so, то у Вас будут реальный файл libfoo.so.1.0, и символьные ссылки foo.so и нечто so.1, указывающее на libfoo.so.1.0. И если Вы установите версию 1.1, не удаляя другую, то у Вас будет libfoo.so.1.1, и libfoo.so.1 и libfoo.so теперь укажут на новый, но любой код, который требует, чтобы точная версия могла использовать libfoo.so.1.0 файл. Код, который просто полагается на версию 1 API, но не заботится, ли это 1.0 или 1.1, укажет libfoo.so.1. Как orip, на который указывают в комментариях, это объяснено хорошо в http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html .

В Вашем случае, Вы могли бы сходить с рук symlinking libpthread_rt.so.1 к libpthread_rt.so. Никакие гарантии, что это не взломает Ваш код и съест Ваши телевизионные ужины, все же.

18
задан oxbow_lakes 9 September 2009 в 07:29
поделиться

1 ответ

В Scala, когда вы пишете var foo , компилятор Scala автоматически генерирует сеттер (называемый foo _ = ) и получатель (называемый foo ) для него и устанавливает поле как частное (вы увидите его как частное, если вы декомпилируете класс, имеющий «общедоступные» поля Scala, с помощью javap ). Вот что означает ошибка «метод foo_ = ничего не отменяет». В своей характеристике вы не определили метод foo _ = , а для установщика и получения общедоступного поля всегда приходят парами.

Если вы не указываете значение по умолчанию в свойство (т.е. абстрактный метод), то ключевое слово override не требуется. Следовательно, в вашем первом примере геттер переопределяет абстрактный метод и сеттер ... он просто есть. Компилятор не жалуется. Но когда вы предоставляете фактическую реализацию метода в трейте, вам нужно специально написать ключевое слово override при замене. При записи protected var foo вы не указали ключевое слово override для получателя, а при записи override protected var foo вы также указали компилятору этот метод foo _ = должен быть переопределен, но признак не имеет такого метода.

Кроме того, логически вы не можете действительно переопределить def с помощью var (учитывая строгий подход к переопределению, как в предыдущем абзаце). def логически является функцией (вы даете ей некоторый ввод, она производит вывод). var аналогична функции без аргументов, но также поддерживает установку его значения на что-нибудь еще, операция, которая не поддерживается функцией. Вместо этого, если вы измените его на val , все будет в порядке. Это похоже на функцию, которая всегда дает один и тот же (кешированный) результат.

Если вы хотите, чтобы поведение было похоже на var , вы можете сделать что-то вроде этого (указав явные сеттеры и геттеры):

class Wibble extends SomeTrait {
  private var bar = "Hello"
  override protected def foo = bar
  protected def foo_=(v: String) { bar = v}
}

Теперь вы можете делать все, что могли, с var :) .

val x = new Wibble
println(x.foo) // yields "Hello"
x.foo = "Hello again"
println(x.foo) // yields "Hello again"
21
ответ дан 30 November 2019 в 08:53
поделиться
Другие вопросы по тегам:

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