[疑难] DLang 有意思的现象,谁能给个解释先?

jinheking 2007-03-20
import std.cstream;
T delegate(T) foo(T)(T n)
{
  return (T a){ return n += a; };
}

void main()
{
  auto f1 = foo(10);
  dout.writefln(f1(5));
  dout.writefln(f1(5));
  dout.writefln(f1(5));
  dout.writefln(f1(5));

  auto f2 = foo(1.5);
  dout.writefln(f2(0.5));
  dout.writefln(f2(0.5));
  dout.writefln(f2(0.5));
  dout.writefln(f2(0.5));
}

运行结果
15
9510725
9510730
9510735
1
1.5
2
2.5
jinheking 2007-03-20
稍微做一下修改
import std.cstream;
import std.stdio;
T delegate(T) foo(T)(T n)
{
  return (T a){ return n += a; };
}

void main()
{
  auto f1 = foo(10);
  writefln(f1(5));
  dout.writefln(f1(5));
  dout.writefln(f1(5));
  dout.writefln(f1(5));

  auto f2 = foo(1.5);
  dout.writefln(f2(0.5));
  dout.writefln(f2(0.5));
  dout.writefln(f2(0.5));
  dout.writefln(f2(0.5));
}

结果
15
10
15
20
1
1.5
2
2.5


这是为什么?
oldrev 2007-03-20
delegate(T) 的模板用法我真没见过,D总是让人惊讶
qiezi 2007-03-20
这个我以前问过了,原因是D的闭包不是真的闭包,它没有完整保存下当前堆栈,所以委托里面用到的n值指向的堆栈总在变化,被函数调用不断覆盖。

这种情况下可以用一个对象来保存:
class Foo{
  private int value_;
  public this(int value){value_ = value;}
  public int foo(int a){return a + 3};
}

auto f = new Foo;
auto dg = &f.foo;
dg(3);
dg(4);
// ...


C#好像也有一样的问题,这是所有基于C堆栈的语言都会碰到的,一些动态语言自己实现堆栈,可能会解决掉这问题。
tomqyp 2007-03-20
什么闭包呢
google了一下,也没找到详细的解释
jinheking 2007-03-21
qiezi 写道
这个我以前问过了,原因是D的闭包不是真的闭包,它没有完整保存下当前堆栈,所以委托里面用到的n值指向的堆栈总在变化,被函数调用不断覆盖。

这种情况下可以用一个对象来保存:
class Foo{
  private int value_;
  public this(int value){value_ = value;}
  public int foo(int a){return a + 3};
}

auto f = new Foo;
auto dg = &f.foo;
dg(3);
dg(4);
// ...


C#好像也有一样的问题,这是所有基于C堆栈的语言都会碰到的,一些动态语言自己实现堆栈,可能会解决掉这问题。



为什么f(0.5)就没有问题哪?还有,我下面修改的就是正常的?这怎么解释?
如果是闭包的问题,那么另外两个例子是不是也不应该出现正确结果呀?
qiezi 2007-03-21
第2个也是错误的吧?
15
10
15
20
应该是
15
20
25
30


另外2个程序加上-O编译。运行都会AV,有兴趣反汇编看一下吧。。
qiezi 2007-03-25
http://www.prowiki.org/wiki4d/wiki.cgi?LexicalClosures
里面有这样一个例子,它已经注明了:
引用

Note: this won't work in D. It's for illustration purposes only.
Global site tag (gtag.js) - Google Analytics