4

是否有 scala 等效于 python __getattr__ / __setattr__(和其他__*__方法?)。一些内置的东西或者一些特征?

4

2 回答 2

11

因为你必须等到有更多洞察力的人描述新的 Scala 2.10 反射 API __getattr____setattr__(当然:它永远不会直接翻译。这完全取决于您的用例。如果您只想要一个动态类,将来会有一个Dynamic特征;如果您只想要一点点,那么围绕模式匹配进行设计可能是一个明显的选择。)

至于Python中的许多其他__*__方法:

全球事物

  • __call__apply()// 行为几乎相同
  • __metaclass__// 用例依赖:
    • 目前class继承或trait混合可能有用
    • 在许多情况下,元类所做的只是避免调用的实例构造super();在 Scalasuper()中总是在构造函数中调用。
  • __repr__, __str__toString()
  • __eq__equals()
  • __init__// 在类体中隐式调用
  • __new__// 不直接存在;取决于用例早期初始化
  • __del__//缺失
  • __nonzero__// 不是真的,除了implicit def toBool[MyType](a: MyType): Boolean = ...

容器类型

  • __len__lengthsize或者容器中的任何约定
  • __getitem__apply(i: IndexType)// 容器是 Scala 中的函数
  • __setitem__update(i: IndexType, v: ValueType)
  • __delitem__// 不需要特殊处理;集装箱公约
  • __iter__foreach(block: ValueType => Unit)// 有返回值: map,flatMap

值得注意的是,它在 Scalaapplyupdate特别,就像它们的 Python 对应物一样。它们允许以下语法:

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

类似地,正如 Python__iter__允许使用类似的语法(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), ...</li>

上下文管理器

  • __enter__, __exit__// 在大多数情况下,函数参数实现相同的目的

另请参阅:Scala 的“魔法”函数列表

于 2012-05-18T21:19:27.050 回答
2

我不确定这里有什么意义。Scala 的统一访问原则意味着“字段”和方法共享相同的接口——因为事实上,Scala 中的“字段”是 getter 和 setter。

换句话说,您可以像这样替换它们:

var x: Int = 0

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

getter 和 setter 方法将控制对您声明的私有字段的访问。

现在,如果您想要的只是一种提供非静态字段的方法,那么您必须查看 Dynamic trait。它在 2.9.2 之前是实验性的,但它将在 2.10 上可用,尽管在一个标志后面警告人们这个特性是危险的(因为它引入了动态类型,但如果你不认为动态类型是危险的,你应该美好的)。

于 2012-05-18T23:17:28.970 回答