我将一个对象包装在一个代理中,然后迭代它.如何控制它迭代的键?
如果我不覆盖键,代理可以工作:
var obj = {"hello": "world"}
var proxy = new Proxy(obj, {})
for (var key in proxy){
console.log(key)
}
// logs "Hello"
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改ownKeys处理程序中的键,则不记录任何内容.
var obj = {"hello": "world"}
var proxy = new Proxy(obj, {
ownKeys: function(){
return ["a", "b"]
}
})
for (var key in proxy){
console.log(key)
}
// Logs nothing
Run Code Online (Sandbox Code Playgroud)
如果我返回"hello"作为ownKeys唯一"hello"记录的一部分.
显然enumerateES6中有陷阱,但它已从ES7中删除.
是否仍然可以for...in使用代理控制循环?为什么enumerate从规范中删除了?
我正在尝试创建一个对象代理。属性/属性查找可以通过简单地实现__getattribute__,__setattr__和__delattr__方法来完成。但是,其他功能如len(x), x[], bool(x)需要其他 dunder 方法__len__, __getitem__, __bool__来实现。如果您没有在代理类上实现这些,但是您代理的对象支持它们,您的代理将不完整并导致运行时错误。
因此,我想拥有一份我需要实施的所有事情的综合清单,但我在网上找不到任何可靠的清单。
这是我从typing和builtins模块中获得的 97 个独特的 dunder 方法名称。我知道他们中的很多人在做什么,但有些人我不知道。为我的代理类实现所有或大部分它们会很痛苦,所以如果有解决方法我会很高兴。
__abs__
__add__
__aenter__
__aexit__
__aiter__
__and__
__anext__
__await__
__bool__
__bytes__
__call__
__class__
__cmp__
__complex__
__contains__
__delattr__
__delete__
__delitem__
__delslice__
__dir__
__div__
__divmod__
__enter__
__eq__
__exit__
__float__
__floordiv__
__format__
__fspath__
__ge__
__get__
__getattribute__
__getitem__
__getnewargs__
__getslice__
__gt__
__hash__
__iadd__
__iand__
__import__
__imul__
__index__
__init__
__init_subclass__
__instancecheck__
__int__
__invert__
__ior__
__isub__
__iter__
__ixor__
__le__
__len__ …Run Code Online (Sandbox Code Playgroud) 我只是想着实施std::string::substr.它返回一个新std::string对象,这对我来说似乎有点浪费.为什么不返回一个引用原始字符串内容的对象,并且可以隐式赋值给std::string?一种对实际复制的懒惰评价.这样的类看起来像这样:
template <class Ch, class Tr, class A>
class string_ref {
public:
// not important yet, but *looks* like basic_string's for the most part
private:
const basic_string<Ch, Tr, A> &s_;
const size_type pos_;
const size_type len_;
};
Run Code Online (Sandbox Code Playgroud)
这个类的公共接口将模仿真实的所有只读操作std::string,因此使用将是无缝的.std::string然后可以有一个新的构造函数,string_ref因此用户永远不会更聪明.在您尝试"存储"结果的那一刻,您最终会创建一个副本,因此引用没有真正的问题指向数据,然后在其背后进行修改.
想法是这样的代码:
std::string s1 = "hello world";
std::string s2 = "world";
if(s1.substr(6) == s2) {
std::cout << "match!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
std::string总共不会构造2个对象.对于执行大量字符串操作的代码来说,这似乎是一种有用的优化.当然,这不仅适用于std::string任何可以返回其内容子集的类型.
据我所知,没有实现这样做.
我想问题的核心是:
给定一个可以根据需要隐式转换为类的类std::string,是否符合库编写者的标准,将成员的原型更改为返回类型?或者更一般地说,库编写者是否有余地在这些类型的情况下作为优化返回"代理对象"而不是常规对象?
我的直觉是,这是不允许的,原型必须完全匹配.鉴于您不能单独重载返回类型,这将使图书馆编写者无法利用这些类型的情况.就像我说的,我认为答案是否定的,但我想我会问:-).
我想知道属于集合类的对象是否在迭代时可以知道它正在被迭代并知道它所属的集合类?例如
<?php
class ExampleObject
{
public function myMethod()
{
if( functionForIterationCheck() ) {
throw new Exception('Please do not call myMethod during iteration in ' . functionToGetIteratorClass());
}
}
}
$collection = new CollectionClass([
new ExampleObject,
new ExampleObject,
new ExampleObject
]);
foreach($collection as $item) {
$item->myMethod(); //Exception should be thrown.
}
(new ExampleObject)->myMethod(); //No Exception thrown.
Run Code Online (Sandbox Code Playgroud)
我做了一些谷歌,但找不到任何东西,我猜这是不可能的,因为它打破了某个地方的OOP校长,但我想我还是要问!