是否有 scala 等效于 python __getattr__ / __setattr__(和其他__*__方法?)。一些内置的东西或者一些特征?
2 回答
因为你必须等到有更多洞察力的人描述新的 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__⇝length,size或者容器中的任何约定__getitem__→apply(i: IndexType)// 容器是 Scala 中的函数__setitem__→update(i: IndexType, v: ValueType)__delitem__// 不需要特殊处理;集装箱公约__iter__→foreach(block: ValueType => Unit)// 有返回值:map,flatMap
值得注意的是,它在 Scalaapply中update很特别,就像它们的 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 的“魔法”函数列表
我不确定这里有什么意义。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 上可用,尽管在一个标志后面警告人们这个特性是危险的(因为它引入了动态类型,但如果你不认为动态类型是危险的,你应该美好的)。