В Scala я вижу такую особенность, как объектно-приватная переменная. На моем не очень богатом опыте работы с Java я научился все закрывать (делать закрытым) и открывать (предоставлять средства доступа), если необходимо. Scala вводит еще более строгий модификатор доступа. Всегда ли использовать его по умолчанию? Или мне следует использовать его только в некоторых конкретных случаях, когда мне нужно явно ограничить изменение значения поля даже для объектов того же класса? Другими словами, как мне выбирать между
class Dummy {
private var name = "default name"
}
class Dummy {
private[this] var name = "default name"
}
Второй более строгий и мне он нравится, но всегда ли его использовать или только при наличии веской причины?
Отредактированный: Как я вижу здесь private[this]
лишь некоторые подслучай и вместо того , что this
я могу использовать другие модификаторы: «пакет, класс или одноплодный объект». Так что оставлю это для особого случая.
Ответы:
Я не думаю, что это слишком важно, поскольку любые изменения в любом случае коснутся только одного класса. Таким образом, наиболее важная причина , чтобы предпочесть
private
болееprotected
болееpublic
не применяется.Используйте
private[this]
там, где действительно имеет значение производительность (поскольку таким образом вы получите прямой доступ к полю вместо методов). В противном случае, просто оседают на одном стиле , так что люди не должны выяснить , почему это свойствоprivate
и что одинprivate[this]
.источник
private
любом случае встроить вызовы методов доступа, сгенерированные с помощью , поэтому влияние должно быть нулевым или, по крайней мере, очень небольшим.Есть случай, когда
private[this]
требуется выполнить компиляцию кода. Это связано с взаимодействием обозначения дисперсии и изменяемых переменных. Рассмотрим следующий (бесполезный) класс:Таким образом, этот класс предназначен для хранения необязательного значения, возврата его как опции и предоставления пользователю возможности вызывать
makeEmpty
для очистки значения (отсюда и var). Как уже говорилось, это бесполезно, кроме как для демонстрации сути.Если вы попытаетесь скомпилировать этот код
private
вместоprivate[this]
него, вы получите следующее сообщение об ошибке:Эта ошибка возникает из-за того, что value является изменяемой переменной ковариантного типа T (+ T), что обычно является проблемой, если только не помечено как частное для экземпляра с помощью
private[this]
. Компилятор имеет специальную обработку проверки дисперсии для обработки этого особого случая.Так что это эзотерично, но есть случай, когда
private[this]
требуется большеprivate
.источник
private var name
доступен из любого методаclass Dummy
(и его спутникаobject Dummy
).private[this] var name
доступен только из методовthis
объекта, но не из других объектовclass Dummy
.источник
так что вы можете делать приватные [это] каждый раз, когда захотите, но у вас могут возникнуть проблемы, если вам нужно направить их
источник
private[this]
не равноprotected[this]
.protected[this]
позволяет экземплярам подкласса получить доступ к члену.this.y == that.y
использовать ни приватное, ни приватное [это], я только что попробовал обаЭто было протестировано с использованием scala 2.11.5. Рассмотрим код ниже
он будет компилироваться и работать как этот код java (1.8)
однако, если вы используете модификатор '[this]', приведенный ниже код не будет компилироваться
Это связано с тем, что в первом случае «x» доступен на уровне класса, тогда как во втором случае это более строгий уровень экземпляра. Это означает, что к 'x' можно получить доступ только из экземпляра, которому он принадлежит. Так что this.x подходит, а другой - нет.
Вы можете обратиться к разделу 13.5 книги «Программирование на Scala: подробное пошаговое руководство» для получения дополнительных сведений о модификаторах доступа.
источник
private[this]
означает. Обратите внимание на первое предложение.При добавлении области видимости к модификатору private ( private [X] ) он эффективно ведет себя как «до» X, где X обозначает некоторый включающий пакет, класс или одноэлементный объект.
Например, private [bar] , где bar - это пакет, означает, что каждый экземпляр каждого класса, принадлежащего bar package, может получить доступ к любому члену, который ограничивает модификатор.
В случае private [this] это означает, что член доступен только для каждого экземпляра. Это становится более понятным в следующем примере:
Как видите, второй Foo не имеет проблем, поскольку любой экземпляр может получить доступ к закрытому значению val i. Однако для первого Foo возникает ошибка, поскольку каждый экземпляр не может видеть i другого экземпляра.
Хорошая практика - писать приватные [this], так как это накладывает более серьезные ограничения.
источник
В большинстве языков программирования ООП, таких как java, частные поля / методы означают, что эти частные поля / методы недоступны вне класса. Однако экземпляры / объекты одного класса могут иметь доступ к закрытым полям объектов с помощью оператора присваивания или с помощью конструктора копирования. В Scala private [this] является закрытым объектом, что гарантирует, что любой другой объект того же класса не может получить доступ к закрытым членам [this].
пример
1. Без приватного [this]
2. Использование приватного [this]
Следовательно, private [this] гарантирует, что поле _password доступно только с этим.
источник
Чтобы подробнее остановиться на проблеме производительности, упомянутой Алексеем Романовым, вот некоторые из моих предположений. Цитаты из книги «Программирование на Scala: подробное пошаговое руководство, 2-е издание», раздел 18.2:
Чтобы проверить это, этот код вызовет ошибку компиляции:
Scala жалуется на
error: ambiguous reference to overloaded definition
. Добавление ключевого слова override кdata_=
не поможет, должно доказать, что метод сгенерирован компилятором. Добавлениеprivate
ключевого слова в переменнуюdata
все равно вызовет эту ошибку компиляции. Однако следующий код компилируется нормально:Итак, я думаю,
private[this]
это помешает scala генерировать методы получения и установки. Таким образом, доступ к такой переменной сэкономит накладные расходы на вызов методов получения и установки.источник
Лучше использовать,
private[this]
если вы планируете синхронизировать переменную.Вот хороший пример из руководства по стилю scala команды Spark :
источник