Ter*_*nce 0 c# perl dynamic .net-4.0 autovivification
试图围绕perl的Autovivification并根据它听起来的样子,它似乎与C#中的动态类似,因为动态对象直到运行时才被分配类型,或者我完全不在这里.如果是这样,那么我是否可以在C#中建立一个有意义的理念?
编辑
好吧所以我显然已经离开了.因此,作为2部分问题的第二部分,在C#中有什么概念上可比的吗?要明确我正在寻找一个与Autovivification相当的C#概念.不必完全相同,但在概念上足够接近才有意义.正如我所说的那样,我绝不是任何想象中的perl黑客或蟒蛇黑客,但我熟悉基于c语言的C,C++,C#,java,javascript.我正在考虑C#的动态,但是现在我正在考虑根据这里的信息进行延迟加载,如果这有帮助....
我不能和C#说话,但用外行人的话来说,Perl的自动更新是在需要时立即从未定义的值创建容器对象的过程.
尽管Perl的大多数都是非常动态的,但Perl的解除引用语法明确指定了编译时引用的类型.这允许解释器在定义变量之前知道变量需要什么.
my $var; # undefined
# to autovivify to an array:
@$var = 1..5; # @ here implies ARRAY
$$var[4] = 5; # square brackets imply ARRAY
$#$var; # $# implies ARRAY (returns the last index number)
# to autovivify to a hash:
%$var = (a => 1); # % implies HASH
$$var{asdf} = 5; # curly braces imply HASH
Run Code Online (Sandbox Code Playgroud)
这个列表可能会更长,但应该给你一个想法.
所以基本上,当你有这样一条线:
my $var;
$var->[1]{x}[3]{asdf}
Run Code Online (Sandbox Code Playgroud)
Perl看起来在右侧->
,看到方括号.这意味着调用者$var
必须是数组引用.由于调用者未定义,Perl创建一个新数组并将其引用安装到$var
.然后对每个后续解除引用重复相同的过程.
所以上面这一行真的意味着:
(((($var //= [])->[1] //= {})->{x} //= [])->[3] //= {})->{asdf};
这是相当可怕的,因此自动化.(//=
是perl 5.10+中的定义或赋值运算符)
更新:
按照CJM的评论,把这个分为一般非perl的条款,以另一种语言来实现自动激活,你需要一个懒惰的对象,通过支持索引[...]
和{...}
.执行这些索引操作中的任何一个时,该对象将使用数组或散列替换自身.每次访问对象时,如果单元格为空,则应返回另一个惰性对象.
obj = new lazy_obj()
level1 = obj[4] # sets obj to be an array, returns a new lazy_obj for level1
level2 = level1{asdf} # sets level1 (and obj[4]) to a hash,
# returns a new lazy_obj for level2
Run Code Online (Sandbox Code Playgroud)
所以基本上你需要两件事,即创建支持使用数组和散列下标(或等价物)进行索引的对象的能力,以及一种机制,使得一个对象可以在内存中用另一个对象替换自己(或者可以将自己锁定到一种解释,然后在内部存储新对象.
类似下面的伪代码可能是一个开始:
class autoviv {
private var content;
method array_subscript (idx) {
if (!content) {
content = new Array();
}
if (typeof content == Array) {
if (exists content[idx]) return content[idx];
return content[idx] = new autoviv();
} else {
throw error
}
}
method hash_subscript (idx) {
if (!content) {
content = new Hash();
}
if (typeof content == Hash) {
if (exists content{idx}) return content{idx};
return content{idx} = new autoviv();
} else {
throw error
}
}
// overload all other access to return undefined, so that the value
// still looks empty for code like:
//
// var auto = new autoviv();
// if (typeof auto[4] == autoviv) {should run}
// if (auto[4]) {should not run}
}
Run Code Online (Sandbox Code Playgroud)