是否有 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 上可用,尽管在一个标志后面警告人们这个特性是危险的(因为它引入了动态类型,但如果你不认为动态类型是危险的,你应该美好的)。