Scala эквивалент python __getattr__ / __setattr__

Есть ли scala-эквивалент python __getattr__ / __setattr__ (и других __*__ методов?). Что-то встроенное или, может быть, какие-то черты?


person ts.    schedule 18.05.2012    source источник
comment
Я действительно не знаю Python, но вы имеете в виду такие вещи, как методы getOrElse или объекты Scala Option? Оба помогают предотвратить исключения нулевого указателя, если это то, что вы ищете.   -  person aishwarya    schedule 19.05.2012
comment
__*attr__() используются для управления поведением при доступе к атрибутам объекта.   -  person Ignacio Vazquez-Abrams    schedule 19.05.2012
comment
Можете ли вы более конкретно рассказать о том, чем вы хотите заниматься? Это слишком широко.   -  person dhg    schedule 19.05.2012
comment
@dhg для динамического добавления и управления полями во время выполнения   -  person ts.    schedule 20.05.2012


Ответы (2)


Что касается __getattr__ и __setattr__, вам придется подождать, пока кто-нибудь с большей проницательностью не опишет новый API отражения Scala 2.10. (И, конечно же: он никогда не будет напрямую переводиться. Это полностью зависит от вашего варианта использования. Если вам просто нужен динамический класс, в будущем будет черта Dynamic; если вы просто хотите немного этого, тогда разработка на основе сопоставления с образцом может быть очевидным выбором.)

Что касается множества других __*__ методов в Python:

Глобальные вещи

  • __call__apply() // поведение практически идентично
  • __metaclass__ // use case dependent:
    • currently class inheritance or trait mixins may be useful
    • во многих случаях все, что делает этот метакласс, - это создание экземпляра, которое избегает вызова super(); в Scala super() всегда вызывается в конструкторе.
  • __repr__, __str__toString()
  • __eq__equals()
  • __init__ // неявно вызывается в теле класса
  • __new__ // прямо не существует; в зависимости от варианта использования ранняя инициализация
  • __del__ // отсутствует
  • __nonzero__ // не совсем, кроме implicit def toBool[MyType](a: MyType): Boolean = ...

Типы контейнеров

  • __len__length, size или как там принято в контейнере
  • __getitem__apply(i: IndexType) // контейнеры - это функции в Scala
  • __setitem__update(i: IndexType, v: ValueType)
  • __delitem__ // особой обработки не требуется; контейнерная конвенция
  • __iter__foreach(block: ValueType => Unit) // с возвращаемым значением: map, flatMap

Примечательно, что apply и update являются особыми в Scala, как и их аналоги в Python. Они допускают следующий синтаксис:

val x = collection(elem) // val x = collection.apply(elem)
collection(elem) = y // collection.update(elem, y)

Точно так же, как __iter__ Python допускает синтаксис типа (el for el in container) foreach и map позволяет говорить for (el <- container) yield el.

Операторы

обычно не требуется специальной обработки, поскольку мы можем определять их напрямую:

  • __add__, __sub__,… // просто определите def + (arg: T) или def - (arg: T)

это также включает операторы сравнения

  • __lt__, __ge__def <(other: T), def <=(other: T)

однако, как и в Python, в компиляторе есть несколько особых случаев для сложных задач:

  • __radd__, __rsub__,… // правоассоциативные операторы; ок. def +: (arg: T) или def -: (arg: T) (добавьте :)
  • __iadd__, __isub__,… // модифицирующие операторы: def += (arg: T),…

Менеджер контекста

  • __enter__, __exit__ // в большинстве случаев аргумент функции служит той же цели

См. Также: Список волшебных функций Scala

person Debilski    schedule 18.05.2012
comment
(Что-то не так, кроме того факта, что __getattr__ и __setattr__ явно отсутствуют?) - person Debilski; 19.05.2012

Я не уверен, в чем здесь смысл. Единый принцип доступа Scala означает, что «поля» и методы используют один и тот же интерфейс, потому что, по сути, «поля» в Scala являются геттерами и сеттерами.

Другими словами, вы можете заменить их так:

var x: Int = 0

private[this] var _x = 0
def x = _x
def x_=(n: Int) { _x = n }

Методы получения и установки будут контролировать доступ к объявленному вами частному полю.

Теперь, если все, что вам нужно, это способ предоставить нестатические поля, вам нужно взглянуть на черту Dynamic. Это экспериментальная версия до 2.9.2, но она будет доступна в 2.10, хотя и за флажком, предупреждающим людей, что эта функция опасна (потому что она вводит динамическую типизацию, но если вы не думаете, что динамическая типизация опасна, вам следует отлично).

person Daniel C. Sobral    schedule 18.05.2012
comment
__getattr__ и __setattr__ не имеют прямого отношения к единому принципу доступа в Python (по крайней мере, с тех пор, как был установлен декоратор property). - person Debilski; 19.05.2012