最好问问你为什么想要这个。如果我在 C 中看到这样的代码,我会强烈劝阻作者不要写这个:它看起来像是一种故意混淆的方式。
f
的唯一目的似乎是允许突变a
。在这种情况下,函数签名很奇怪。为什么不:
typedef void (*func)(int, int);
哪个包含索引以及您要设置的值?在这种情况下,我们甚至可以给这个签名起一个好听的名字,一个“setter”。
typedef void (*setter)(int, int);
有了这个,C代码就简单直接了,
void foo(int i, int val) { a[i] = val; }
void goo(setter f) {
int i = 0;
for(; i < 2; ++i) f(i, 7);
}
并且这个的 Python 翻译也很简单。
如果你真的需要这样的东西,只需在可调用的东西中捕捉突变的想法,然后返回它。这就是指针的真正含义,对吧?例如:
a = [0, 0]
def foo(i):
def mutate(v):
a[i] = v
return mutate
def goo(f):
for i in range(2):
f(i)(7)
if __name__ == '__main__':
goo(foo)
print a
指针不是指针,因为它在物理上由“星”运算符表示。它是一个指针,因为我们可以引用和改变它。我们可以用简单的函数来做到这一点:
a = [4, 17]
def foo(i):
def ref():
return a[i]
def mutate(v):
a[i] = v
return { 'ref' : ref, 'mutate' : mutate }
def goo(f):
for i in range(2):
ptr = f(i)
print "at", i, "I see", ptr['ref']()
ptr['mutate'](7)
if __name__ == '__main__':
goo(foo)
print a
如果我们想让它更漂亮,我想我们可以使用类。
a = [4, 17]
def foo(i):
class Ptr(object):
def __init__(self): pass
def ref(self):
return a[i]
def set(self, v):
a[i] = v
return Ptr()
def goo(f):
for i in range(2):
ptr = f(i)
print "at", i, "I see", ptr.ref()
ptr.set(7)
if __name__ == '__main__':
goo(foo)
print a
但同样,我不会盲目地使用它:我宁愿看到真正的代码,看看你想要做什么。